KnowDotNet NetRefactor

Protect Events That Fire During InitializeComponent

by Les Smith
Print this Article Discuss in Forums

My Form hangs in loading when I have event handlers that expect multiple controls to have been initialized.  The reason may well be caused by events firing during InitializeComponent and your other controls are not yet populated.

I have a form with ComboBoxes.  In the designer, I have populated some Items.  In the SelectedIndexChanged event of the ComboBox, I have placed code to modify the contents of a SubItem in a ListView.  That Code is shown below.

   Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, _
      
ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
      
Me.lv.Items(index).SubItems(1).Text = MeComboBox1.Text
  
End Sub

The problem is that because I have populated some Items in the ComboBox at design time, the event shown above will fire as soon as it is created and the first Item is added by the forms constructor, InitializeComponent.  However, the ListView does not have any items in it at design time; I have code to load the ListView at Form_Load time.  The firing of the event causes the form to hang somewhere in never land, because if I press Ctrl-Break, I receive the message, "There is no code at this location."

So what's the fix?  First, I added a module level Boolean, called formLoading, and then added the following code to the previously shown event handler.

   Private formLoading As Boolean

   Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, _
      
ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
      
If formLoading Then Exit Sub
      Me.lv.Items(index).SubItems(1).Text = MeComboBox1.Text
  
End Sub

Initially, I added the following line to the Windows Form Designer code.

   Public Sub New()
      
MyBase.New()

      
'This call is required by the Windows Form Designer.
      InitializeComponent()

      
'Add any initialization after the InitializeComponent() call
      formLoading = True

It did not take long for reality to wake me up to the fact that the error was being caused by InitializeComponent and that setting the formLoading to True was happening too late.  You can fix the problem one of two ways.  First, you can move the setting of the Boolean to before the InitializeComponent call.  Even though Microsofts comment says that it should go after the InitializeComponent call, it does work.  That code is shown below.

   Public Sub New()
      
MyBase.New()

      formLoading =
True

      
'This call is required by the Windows Form Designer.
      InitializeComponent()

      
'Add any initialization after the InitializeComponent() call

The other way to fix it is to initialize the Boolean as it is declared, as shown below.  The Boolean will be initialized to True before the forms constructor is called.

   Private formLoading As Boolean = True

The bottom line is that if you are going to place code in events that depend on the contents of of other controls, make sure that you protect those event handlers.  
Windows programming can be a ball, can't it?


Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing