populating one checkedlistbox with another (checkedlistbox)
-
22-09-2019 - |
Question
I am having difficulties populating a checkedlistbox (CLB) based on the selection(s) made in another. It should also be noted that I have a "Select All" checkbox at the top that checks/unchecks all of the items in the first CLB. Here's the code:
Private Sub chkSelectAll_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkSelectAll.CheckedChanged
For i As Integer = 0 To clb1.Items.Count - 1
clb1.SetItemChecked(i, chkSelectAll.Checked)
Next
If chkSelectAll.Checked = False Then
clb2.Items.Clear()
End If
End Sub
Private Sub clb1_ItemCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles clb1.ItemCheck
Dim i As Integer = clb1.SelectedIndex
For j As Integer = 0 To al_2.Count - 1
If i = -1 Then
For k As Integer = 0 To al_2.Count - 1
If Not clb2.Items.Contains(al_2(k).sDate) Then
clb2.Items.Add(al_2(k).sDate)
Else : k += 1
End If
Next
ElseIf (e.NewValue = CheckState.Checked And al_2(j).sName = al_1(i)) Then
clb2.Items.Add(al_2(j).sDate)
ElseIf (e.NewValue = CheckState.Unchecked And al_2(j).sName = al_1(i)) Then
clbProdBkups.Items.Remove(al_2(j).sDate)
End If
Next
End Sub
The first CLB is populated with an arraylist of values on the button click event. Based on whatever is checked in the first CLB, corresponding values from an arraylist of structures should fill the second CLB. The following code partially works until the "Select All" checkbox is clicked at which point if other values have been selected before "Select All" is checked, the second CLB is filled with the correct number of corresponding values BUT only those of the most recently selected item of the first CLB instead of all of corresponding values of all of the items that were not already selected.
Any insights will be greatly appreciated.
~8th
Solution
i have used an Dictionary to map key clb1-items to the corresponding clb2-items. Have a look at my sample code which runs fine:
Private mytable As New Generic.Dictionary(Of String, List(Of String))
Sub New()
' Dieser Aufruf ist für den Windows Form-Designer erforderlich.
InitializeComponent()
mytable.Add("Object A", New List(Of String)(New String() {"Object A1", "Object A2", "Object A3"}))
mytable.Add("Object B", New List(Of String)(New String() {"Object B1", "Object B2", "Object B3"}))
mytable.Add("Object C", New List(Of String)(New String() {"Object C1", "Object C2", "Object C3"}))
mytable.Add("Object D", New List(Of String)(New String() {"Object D1", "Object D2", "Object D3"}))
mytable.Add("Object E", New List(Of String)(New String() {"Object E1", "Object E2", "Object E3"}))
For Each key As String In mytable.Keys
Me.clb1.Items.Add(key, False)
Next
End Sub
Private Sub chkSelectAll_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ChkSelectAll.CheckedChanged
For i As Int32 = 0 To Me.clb1.Items.Count - 1
Me.clb1.SetItemChecked(i, ChkSelectAll.Checked)
Next
End Sub
Private Sub clb1_ItemCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles clb1.ItemCheck
Dim key As String = DirectCast(Me.clb1.Items(e.Index), String)
If e.NewValue = CheckState.Checked Then
For Each value As String In mytable(key)
Me.Clb2.Items.Add(value, False)
Next
Else
For Each value As String In mytable(key)
Me.Clb2.Items.Remove(value)
Next
End If
End Sub
Regards, Tim
EDIT: When you dont want to use Generics you can use Hashtable and Arraylist instead. My sample code is almost the same. Have a look:
Private mytable As New Hashtable()
Sub New()
' Dieser Aufruf ist für den Windows Form-Designer erforderlich.
InitializeComponent()
mytable.Add("Object A", New ArrayList(New String() {"Object A1", "Object A2", "Object A3"}))
mytable.Add("Object B", New ArrayList(New String() {"Object B1", "Object B2", "Object B3"}))
mytable.Add("Object C", New ArrayList(New String() {"Object C1", "Object C2", "Object C3"}))
mytable.Add("Object D", New ArrayList(New String() {"Object D1", "Object D2", "Object D3"}))
mytable.Add("Object E", New ArrayList(New String() {"Object E1", "Object E2", "Object E3"}))
For Each key As String In mytable.Keys
Me.clb1.Items.Add(key, False)
Next
End Sub
Private Sub chkSelectAll_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ChkSelectAll.CheckedChanged
For i As Int32 = 0 To Me.clb1.Items.Count - 1
Me.clb1.SetItemChecked(i, ChkSelectAll.Checked)
Next
End Sub
Private Sub clb1_ItemCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles clb1.ItemCheck
Dim key As String = DirectCast(Me.clb1.Items(e.Index), String)
If e.NewValue = CheckState.Checked Then
For Each value As String In mytable(key)
Me.Clb2.Items.Add(value, False)
Next
Else
For Each value As String In mytable(key)
Me.Clb2.Items.Remove(value)
Next
End If
End Sub