Riples Riples - 21 days ago 6
Vb.net Question

Selecting same row of multiple listview controls at the same time

In my application I have a form that contains 5 different listview controls. I am trying to achieve two things here which I have become a little stuck on...

1. Is there a way I can make it so when I click on row 3 (for example) of Listview1, it selects row 3 for all listview controls? I have the following code set in my _SelectedIndexChanged event of Listview1 which works correctly, however, I want to make it so if the user clicks on row3 of any listview, it changes all listview controls to row 3.

Private Sub lsvRegisters_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lsvRegisters.SelectedIndexChanged
Try
If Not lsvRegisters.SelectedItems.Count = 0 Then
Dim index As Integer = lsvRegisters.SelectedIndices(0)

If lsvRegister_Hardware.Items.Count > 0 Then lsvRegister_Hardware.Items(index).Selected = True
If lsvRegister_Software.Items.Count > 0 Then lsvRegister_Software.Items(index).Selected = True
If lsvRegister_Processes.Items.Count > 0 Then lsvRegister_Processes.Items(index).Selected = True
If lsvRegister_System.Items.Count > 0 Then lsvRegister_System.Items(index).Selected = True
If lsvRegister_Misc.Items.Count > 0 Then lsvRegister_Misc.Items(index).Selected = True
End If

Catch ex As Exception
CreateLog("Module: lsvRegisters_SelectedIndexChanged()" & vbNewLine & "Exception Error: " & ex.Message)
MsgBox("Exception Error: " & ex.Message, MsgBoxStyle.Critical, "Module: lsvRegisters_SelectedIndexChanged()")
End Try
End Sub


And secondly:

2. Is there a way I can make it so all listview controls have the highlight bar as active colour? Currently it only shows the focused listview control with a blue highlight bar and the others in a dull grey. I want to (if possible) have all listview controls show in blue regardless if it has focus or not.

Any help appreciated.
Thanks

Update
The multiple selection of listview controls is now working as requested, however, once a listview loses focus, it only keeps the first cell highlighted as shown below:

enter image description here

My code for setting up the listview controls comes from a dataset. I have demonstrated the first listview, but all of them are the same.

Try
QueryString = "SELECT * FROM Registers WHERE StoreID = '" & _StoreCode & "'"
Dim ExQry As New MySqlCommand(QueryString, MySQLConn)

Dim da As New MySqlDataAdapter(ExQry)
da.Fill(dsStoreDetail, "StoreDetail")
Dim tempDT As DataTable = dsStoreDetail.Tables("StoreDetail")

If dsStoreDetail.Tables.Count > 0 And dsStoreDetail.Tables(0).Rows.Count > 0 Then
For x = 0 To (dsStoreDetail.Tables(0).Rows.Count - 1)
Dim lvi_RegistersItem As ListViewItem = lsvRegisters.Items.Add(tempDT.Rows(x)("Online").ToString)
lvi_RegistersItem.SubItems.Add(tempDT.Rows(x)("Lane").ToString)
lvi_RegistersItem.SubItems.Add(tempDT.Rows(x)("Host_Name").ToString)
lvi_RegistersItem.SubItems.Add(tempDT.Rows(x)("Reg_Type").ToString)
lvi_RegistersItem.SubItems.Add(tempDT.Rows(x)("Operator").ToString)
lvi_RegistersItem.SubItems.Add(tempDT.Rows(x)("Register_Locked").ToString)

Next
Else
lblEmptyString.Visible = True
End If
dsStoreDetail.Clear()
tempDT = Nothing

Catch ex As Exception
CreateLog("Module: LoadStoreData()" & vbNewLine & "Exception Error: " & ex.Message)
MsgBox("Exception Error: " & ex.Message, MsgBoxStyle.Critical, "Module: LoadStoreData()")
lblEmptyString.Visible = True
End Try


I have set all listview controls to FullRowSelect = True but only at design time - not sure if that matters.

Answer

Right, this is my conclusion for this and it will be made with things named differently from yours, I'm afraid.

To Start off, setup all ListViews to have theese settings:

HideSelection = True
MultiSelect = false

This is what I have placed in all ListViews selected Index changed.

Private Sub ListView2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListView2.SelectedIndexChanged
    If Not Working And ListView2.SelectedIndices.Count <> 0 Then
       UpdateAllListViewes(ListView2.SelectedIndices)
    End If
End Sub

Working is a Private Boolean that is used to avoid unecessary calls to the UpdateAllListViews function. UpdateAllListViews sends all listboxes to the UpdateSelectedIndex function with the Index to light up. As you can see the Working Boolean is updated to True while this executes. This can be skipped, but debugging will turn into a nightmare if something goes wrong.

Private Sub UpdateAllListViewes(ByVal Indexes As ListView.SelectedIndexCollection)
        Working = True
        UpdateSelectedIndex(ListView2, Indexes(0))
        UpdateSelectedIndex(ListView3, Indexes(0))
        UpdateSelectedIndex(ListView4, Indexes(0))
        UpdateSelectedIndex(ListView5, Indexes(0))
        Working = False
    End Sub

And finally how to update the selected indexes:

Private Sub UpdateSelectedIndex(ByVal lv As ListView, ByVal Index As Integer)
    For i As Integer = 0 To lv.Items.Count - 1
        If i = Index Then
            lv.Items(i).Selected = True
            lv.Items(i).BackColor = Color.DodgerBlue
            lv.Items(i).ForeColor = Color.White
        Else
            lv.Items(i).Selected = False
            lv.Items(i).BackColor = Color.White
            lv.Items(i).ForeColor = Color.Black
        End If
    Next
End Sub

DodgerBlue is the SelectedIndex color for a ListView. This should solve both question 1 and 2.