Protect Events That Fire During InitializeComponent | | 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?
|