NOTE: As listed below, the code will Select OK but does NOT deselect the controlled listboxes. I am working on a way to resolve it but left the code here in case it would be helpful to someone in its current state.
For purposes of our discussion, create a Windows Form solution and add 5 ListBoxes to it, named lstFirstNames, lstLastNames, lstAges, lstCities and lstStates respectively. Add several items to each item in the Designer or else add items in code like this:
Designate one of the ListBoxes to be the controlling ListBox. In the example below, lstFirstNames was so chosen. In the Form load event, bind all of the remaining ListBoxes to the controlling ListBox like this:
' Choose a ListBox to be the master and bind all remaining ListBoxes to the master SelectedIndex property. Me.lstAges.DataBindings.Add( _ "SelectedIndex", Me.lstFirstNames, "SelectedIndex") Me.lstCities.DataBindings.Add( _ "SelectedIndex", Me.lstFirstNames, "SelectedIndex") Me.lstStates.DataBindings.Add( _ "SelectedIndex", Me.lstFirstNames, "SelectedIndex") Me.lstLastNames.DataBindings.Add( _ "SelectedIndex", Me.lstFirstNames, "SelectedIndex")
In a similar manner, add bindings for TopIndex also:
Now we need to setup a handler for all of the non Controlling ListBoxes to change the Controlling ListBox SelectedIndex in case the user clicks on one of them:
' Add handler for all ListBoxes but the master ListBox. AddHandler lstAges.SelectedIndexChanged, _ AddressOf IndexChanged AddHandler lstCities.SelectedIndexChanged, _ AddressOf IndexChanged AddHandler lstStates.SelectedIndexChanged, _ AddressOf IndexChanged AddHandler lstLastNames.SelectedIndexChanged, _ AddressOf IndexChanged
The only piece left is to write the SelectedIndexChanged method. This method will actually be called 4 times each time a SelectedIndex is changed as the DataBindings do their work. To avoid unneccessary code execution, a static variable is defined to limit setting lstFirstNames.SelectedIndex to once per each set of updates. If you are not familiar with static variables, they retain their values between method calls. I could have accomplished the same thing by using a Module level variable, but since it will not be used outside of the method itself, I chose to use the static variable because it helps to encapsulate all of the code in the method itself.
Private Sub IndexChanged( _ ByVal sender As Object, ByVal e As System.EventArgs)
' Static variables are only initialized once. Static staticSelectedIndex As Integer = -1
' MsgBox allows us to see intermediate results. ' Note that Sender is CTyped to a couple different types. MsgBox("Static: " & staticSelectedIndex.ToString & vbNewLine & "Sender: " & CType(sender, Control).Name & vbNewLine & "Index: " & CType(sender, ListBox).SelectedIndex.ToString, MsgBoxStyle.Information)
' Set master ListBox SelectedIndex once per change. If CType(sender, ListBox).SelectedIndex <> _ staticSelectedIndex Then staticSelectedIndex = _ CType(sender, ListBox).SelectedIndex Me.lstFirstNames.SelectedIndex = _ staticSelectedIndex End If End Sub 'IndexChanged
Instead of adding a handler to SelectedIndexChanged, you can also use the regular SelectedIndexChanged event and then add all of the remaining ListBoxes to the Handles clause like this:
Private Sub lstAges_SelectedIndexChanged( _ ByVal sender As Object, ByVal e As System.EventArgs) _ Handles lstAges.SelectedIndexChanged, _ lstCities.SelectedIndexChanged, _ lstLastNames.SelectedIndexChanged, _ lstStates.SelectedIndexChanged
' The code would be identical to the above method ' so I did not repeat any of it here.
End Sub 'lstAges_SelectedIndexChanged
Syncronizing ComboBoxes would be similar to the above.