Controls: List Box Synchronization


Think of an event listener as a part of your program that monitors the GUI looking for a particular event to occur, such as when the user scrolls a list box. When the event happens, the listener detects the event and then calls an event handler. An event handler is a method that reacts to a specific event, such as scrolling a particular list box.

There are several things that need to be done to synchronize list boxes, but the two main concerns are

  1. Automatically scroll list box 2 when list box 1 is scrolled by the user (and vice versa), and
  2. Automatically change the highlighted item in list box 2 when the user highlights an item in list box 1.

====

Item 1, Step 1:  Add the following class to your program.  Be SURE you place it outside the Form class.

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' NativeWindow class to listen to operating system messages.
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Class MyListener
   
Inherits
NativeWindow

    Public Event MyScroll(ByVal sender As Object, ByVal e As EventArgs)
       
Const WM_MOUSEACTIVATE As Integer = &H21
       
Const WM_MOUSEMOVE As Integer
= &H200

        Private ctrl As Control

        Public Sub New(ByVal ctrl As System.Windows.Forms.ListBox)
            AssignHandle(ctrl.Handle)
       
End
Sub

        ' Listen for operating system messages
       
Protected Overrides Sub WndProc(ByRef m As Message)
             Const WM_HSCROLL As Integer = &H114
             Const WM_VSCROLL As Integer
= &H115

             If m.Msg = WM_HSCROLL Or m.Msg = WM_VSCROLL Then
                  RaiseEvent MyScroll(ctrl, New EventArgs)
             End
If

             MyBase.WndProc(m)

        End Sub

        Protected Overrides Sub Finalize()
             ReleaseHandle()
             MyBase.Finalize()
        End
Sub

End Class

====

Item 1, Step 2:  At the form-level declare a variety of listeners for the scroll events for each of the listboxes that you want to be mirrored with code like the following

Dim WithEvents scroll1w As MyListener
Dim WithEvents scroll1c As MyListener

====

Item 1, Step 3:  In the Form_load event you associate those listeners with particular form elements:

scroll1w = New MyListener(Me.lstWord)
scroll1c = New MyListener(Me.lstCount)

====

Item 1, Step 4:  Somewhere in your Form class you have to write each event handler itself to listen for the scroll event and then react according to your specifications:

'-----------------------------------------------------------------------------------
' This sub is designed to automatically scroll the lstCount listbox
' whenever the lstWord listbox scrolls. It is associated with the
' scroll event of scroll1w (which is associated with lstWord). When
' lstWord is scrolled, the topIndex of lstCount is set to match the
' top index of lstWord.
'-----------------------------------------------------------------------------------
Private Sub scroll1w_MyScroll(ByVal sender As Object, _
                         ByVal e As System.EventArgs) _
                         Handles scroll1w.MyScroll
     lstCount.TopIndex = lstWord.TopIndex
     lstCount.Refresh()
End
Sub

'-----------------------------------------------------------------------------------
' This sub is designed to automatically scroll the lstWord listbox
' whenever the lstCount listbox scrolls. It is associated with the
' scroll event of scroll1c (which is associated with lstCount). When
' lstCount is scrolled, the topIndex of lstWord is set to match the
' top index of lstCount.
'-----------------------------------------------------------------------------------
Private Sub scroll1c_MyScroll(ByVal sender As Object, _
                         ByVal e As System.EventArgs) _
                         Handles scroll1c.MyScroll
     lstWord.TopIndex = lstCount.TopIndex
     lstWord.Refresh()
End
Sub

You have to provide an event handler to synchronize listbox 1 to listbox 2, and another to synchronize listbox 2 to listbox 1.

====

Item 2, Step 1:  Somewhere in your Form class you have to write each event handler itself to listen for the SelectedIndexChanged event and then react according to your specifications:

'-----------------------------------------------------------------------------------
' This sub is designed to automatically scroll the lstCount listbox
' whenever the lstWord listbox index changes. It is associated with
' the SelectedIndexChanged event of the lstWord control. Whenever the
' selected index of lstWord changes, it then changes the selected index
' of lstCount
'-----------------------------------------------------------------------------------
Private Sub lstWords_SelectedIndexChanged(ByVal sender As System.Object, _
                                         
ByVal e As System.EventArgs) _
                                         
Handles lstWord.SelectedIndexChanged
    
If lstCount.SelectedIndex <> lstWord.SelectedIndex Then
          lstCount.SetSelected(lstWord.SelectedIndex, True)
          lstCount.Refresh()
    
End If
End
Sub

'-----------------------------------------------------------------------------------
' This sub is designed to automatically scroll the lstWord listbox
' whenever the lstCount listbox index changes. It is associated with
' the SelectedIndexChanged event of the lstCount control. Whenever the
' selected index of lstCount changes, it then changes the selected index
' of lstWord
'-----------------------------------------------------------------------------------
Private Sub lstCount_SelectedIndexChanged(ByVal sender As System.Object, _
                                         ByVal e As System.EventArgs) _
                                        
Handles lstCount.SelectedIndexChanged
    
If lstCount.SelectedIndex <> lstWord.SelectedIndex Then
          lstWord.SetSelected(lstCount.SelectedIndex, True)
          lstWord.Refresh()
    
End If
End
Sub

You have to provide an event handler to synchronize listbox 1 to listbox 2, and another to synchronize listbox 2 to listbox 1.


A demo program has been provided for you.  Try downloading it and running it.  Be sure to test it by both scrolling the list boxes as well as by highlighting various items.