Loadイベントが毎回呼ばれる!?

この章では、従来版VBVBAなどとの違いで懸案事項に揚がったことなどを説明します。
これは、「Professional Edition」で発覚している現象です。   現在、自宅で「Express Edition」を使って再現を試みたのですが再現できていません。 再現しようとテストしている環境がここの「マルチドキュメントインタフェース(MDI)のようなものなので簡単すぎるのか、あるはSQLServer環境でないと発生しない(サンプルはMDB)というのかも知れませんが、 複数のメンバで事象を確認しているので間違いはありません。
なお、「カレンダー日付入力」のように明らかに「Hideメソッド」で閉じるようにしている場合は、次の「Showメソッド」「ShowDialogメソッド」では「Loadイベント」が動くことはないようです。

プログラム分割させたクラスライブラリを繰り返し呼び出す時の現象です。
Closeメソッド」かあるいは[×]ボタンで閉じられたクラスライブラリ側のフォームをメニュー等から再起動する場合に「Loadイベント」が動作してしまう、というのがここで説明する事象なのです。
閉じたフォームを再起動させるのであれば「Loadイベント」が動作するのは当たり前だろうと思われるかも知れません。ですが、

'************************************************************************************
' フォーム起動のテスト
'************************************************************************************
Public Class Form1
    ' Load起動スイッチ
    Private g_swLoaded As Boolean = False               ' 初期値はFalse

    '********************************************************************************
    '  Loadイベント
    '********************************************************************************
    Private Sub Form1_Load(ByVal sender As Object, _
                           ByVal e As System.EventArgs) Handles Me.Load
        ' Loadイベントの再起動判定
        If g_swLoaded Then
            MessageBox.Show("Loadイベントが再起動されました。")
        End If
        ' Load起動スイッチにTrueをセット
        g_swLoaded = True
    End Sub

    '--------------------------------<< End of Source >>-----------------------------
End Class
このようなコードを書けばご理解いただけるでしょうか。
このサンプルのように、スイッチとメッセージを記述すると、仕掛けたメッセージが明らかに表示されるのです。

実際のところ、閉じたはずのフォームはメモリ上にある程度(?)保持されているらしく、次の呼び出した時はフォーム上の初期状態やモジュールレベルの変数なども保持されている状態なのです。 ここで問題となったのは、「Loadイベント」内の記述です。

'************************************************************************************
' フォーム起動のテスト
'************************************************************************************
Public Class Form1
    ' Load起動スイッチ
    Private g_swLoaded As Boolean = False               ' 初期値はFalse

    '********************************************************************************
    '  ComboBox_SelectedIndexChangedイベント(集合)
    '********************************************************************************
    Private Sub ComboBox_SelectedIndexChanged(ByVal sender As Object, _
                                              ByVal e As System.EventArgs)
        ' テスト
        Dim strName As String = sender.Name
        MessageBox.Show(strName & " " & sender.Text)
    End Sub

    '********************************************************************************
    '  Loadイベント
    '********************************************************************************
    Private Sub Form1_Load(ByVal sender As Object, _
                           ByVal e As System.EventArgs) Handles Me.Load
        ' Loadイベントの再起動判定
        If g_swLoaded Then
            MessageBox.Show("Loadイベントが再起動されました。")
        End If
        ' Load起動スイッチにTrueをセット
        g_swLoaded = True
        '----------------------------------------------------------------------------
        ' ComboBox1のリストセット
        Dim tblList() As String = New String() {"あああ", "いいい", "ううう"}
        ComboBox1.Items.AddRange(tblList)
        ' ComboBox2のリストセット
        tblList = New String() {"かかか", "ききき", "くくく"}
        ComboBox2.Items.AddRange(tblList)
        ' ComboBox3のリストセット
        tblList = New String() {"さささ", "ししし", "すすす"}
        ComboBox3.Items.AddRange(tblList)
        '----------------------------------------------------------------------------
        ' イベントハンドラに関連付け(SelectedIndexChanged)
        AddHandler ComboBox1.SelectedIndexChanged, _
            AddressOf Me.ComboBox_SelectedIndexChanged
        AddHandler ComboBox2.SelectedIndexChanged, _
            AddressOf Me.ComboBox_SelectedIndexChanged
        AddHandler ComboBox3.SelectedIndexChanged, _
            AddressOf Me.ComboBox_SelectedIndexChanged
    End Sub

    '--------------------------------<< End of Source >>-----------------------------
End Class
Loadイベント」では、フォームの表示前にやっておくべき初期化作業として、コンボに固定リストをセットするとか、イベントを集約させるプロシージャにイベントハンドラを関連付ける、などということを記述することが多いと思います。 この場合、「何度も呼び出される」とは考えませんから、このような記述になるものと思います。
このような記述の「Loadイベント」が複数回呼ばれてしまうと、コンボのリストは同じものが繰り返されて連続してしまうし、「SelectedIndexChangedイベント」の方は1回の操作で複数回発生を繰り返す現象になってしまいますが まさに、その現象に当たってからその原因を探って「Loadイベントの再呼び出し」だということが判明したのです。

原因が判れば、対処そのものは簡単です。
原因が「Loadイベントの再呼び出し」だと判ったので、再呼び出しかどうかを判断して2回目以降は初期化記述を避けるようにするだけで解決できました。

'************************************************************************************
' フォーム起動のテスト
'************************************************************************************
Public Class Form1
    ' Load起動スイッチ
    Private g_swLoaded As Boolean = False               ' 初期値はFalse

    '********************************************************************************
    '  ComboBox_SelectedIndexChangedイベント(集合)
    '********************************************************************************
    Private Sub ComboBox_SelectedIndexChanged(ByVal sender As Object, _
                                              ByVal e As System.EventArgs)
        ' テスト
        Dim strName As String = sender.Name
        MessageBox.Show(strName & " " & sender.Text)
    End Sub

    '********************************************************************************
    '  Loadイベント
    '********************************************************************************
    Private Sub Form1_Load(ByVal sender As Object, _
                           ByVal e As System.EventArgs) Handles Me.Load
        ' Loadイベントの初回起動判定
        If g_swLoaded <> True Then
            '------------------------------------------------------------------------
            ' Load起動スイッチにTrueをセット
            g_swLoaded = True
            '------------------------------------------------------------------------
            ' ComboBox1のリストセット
            Dim tblList() As String = New String() {"あああ", "いいい", "ううう"}
            ComboBox1.Items.AddRange(tblList)
            ' ComboBox2のリストセット
            tblList = New String() {"かかか", "ききき", "くくく"}
            ComboBox2.Items.AddRange(tblList)
            ' ComboBox3のリストセット
            tblList = New String() {"さささ", "ししし", "すすす"}
            ComboBox3.Items.AddRange(tblList)
            '------------------------------------------------------------------------
            ' イベントハンドラに関連付け(SelectedIndexChanged)
            AddHandler ComboBox1.SelectedIndexChanged, _
                AddressOf Me.ComboBox_SelectedIndexChanged
            AddHandler ComboBox2.SelectedIndexChanged, _
                AddressOf Me.ComboBox_SelectedIndexChanged
            AddHandler ComboBox3.SelectedIndexChanged, _
                AddressOf Me.ComboBox_SelectedIndexChanged
        End If
    End Sub

    '--------------------------------<< End of Source >>-----------------------------
End Class
想像はつくと思いますが、このような記述ですね。