【VB.NET極致】コントロール配列の幻影を捨て、AddHandlerで「動的UI」を掌握せよ
VB6からVB.NETへ移行した諸君が、真っ先に直面する「壁」。それは、かつて我々が愛用した `Index` プロパティによるコントロール配列の不在だ。
「なぜ、ボタンを100個並べるだけで、これほどまでにコードが肥大化するのか?」
そう嘆くのは、まだオブジェクト指向の深淵を覗いていない証拠だ。VB6のコントロール配列は、単なるインデックスの羅列に過ぎなかった。だが、.NETにおける `AddHandler` を極めれば、UIは静的な配置物から「動的に生成され、イベントを自律的に集約する生命体」へと進化する。
本稿では、レガシーな思考を破壊し、メモリ効率と保守性を両立させる「真の動的UI管理術」を伝授する。
—
1. なぜ「コントロール配列」を追い求めてはいけないのか
VB6世代のエンジニアがやりがちなのが、`List
.NETにおいてイベント管理の要諦は、「イベント・ハンドラの共有(マルチキャスト・デリゲート)」にある。単一のメソッドを複数のコントロールに紐付けることで、どのコントロールから発火したかを `sender` 引数を通じて特定する。これが、アーキテクトが辿り着くべき標準解だ。
—
2. 実装:動的生成とイベントの一元管理
以下のコードは、動的に生成したボタン群のクリックイベントを、たった一つのメソッドで処理する実戦的なパターンだ。
Imports System.Drawing
Public Class DynamicForm
‘ 動的に生成したコントロールの管理(必要最小限の参照保持)
Private ReadOnly _dynamicButtons As New List(Of Button)
Private Sub InitializeDynamicControls()
For i As Integer = 0 To 9
Dim btn As New Button With {
.Name = “btnDynamic_” & i,
.Text = “操作 ” & i,
.Location = New Point(10, i 35)
}
‘ 【重要】AddHandlerでイベントを登録
‘ AddressOfにより、イベント発生時に指定メソッドを呼び出す
AddHandler btn.Click, AddressOf DynamicButton_Click
Me.Controls.Add(btn)
_dynamicButtons.Add(btn)
Next
End Sub
‘ 複数のコントロールから共有される唯一のハンドラ
Private Sub DynamicButton_Click(sender As Object, e As EventArgs)
‘ senderをキャストして元のオブジェクトを特定
Dim clickedBtn As Button = DirectCast(sender, Button)
‘ どのボタンが押されたかをNameプロパティ等で判別
MessageBox.Show($”実行されたのは: {clickedBtn.Name}”)
End Sub
‘ 【極意】リソースの明示的解放
‘ 大量に動的生成した場合は、Disposeを徹底すること
Protected Overrides Sub Dispose(disposing As Boolean)
If disposing Then
For Each btn In _dynamicButtons
‘ ハンドラの切断と明示的破棄
RemoveHandler btn.Click, AddressOf DynamicButton_Click
btn.Dispose()
Next
_dynamicButtons.Clear()
End If
MyBase.Dispose(disposing)
End Sub
End Class
—
3. シニアエンジニアが意識すべき「メモリの重み」
動的生成で最も恐ろしいのは、「イベントハンドラの残留によるメモリリーク」だ。
`AddHandler` を実行すると、コントロールはイベントハンドラへの参照を保持し続ける。フォームを閉じても、このリンクが切れていないとガベージコレクタ(GC)はメモリを回収できない。
- RemoveHandlerの徹底: 生成したコントロールを破棄する際は、必ず `RemoveHandler` を呼び出し、マネージドヒープ上の繋がりを断ち切ること。
- Disposeの明示: `Control` は `IDisposable` を継承している。`.NET` のGCに頼り切るのではなく、`Dispose()` を呼び出し、ネイティブなWindowsハンドルを即座に解放する規律を持て。
—
4. Windows API連携という「最後の手段」
もし、数千個単位のコントロールを配置し、描画パフォーマンスがボトルネックになるような極限状況に陥ったなら、標準の `Control` クラスを捨てる勇気を持て。
`System.Drawing.Graphics` を用いて、フォームの `OnPaint` イベント内で直接描画する(オーナー描画)のが、真のパフォーマンスチューニングだ。ボタンというオブジェクトを一つずつ生成するのではなく、座標計算と描画命令だけでUIを制御する。これが、レガシー環境で磨き抜かれたプロの「軽さ」である。
—
結論:技術は「道具」であれ
VB.NETは古い言語ではない。それは、OSの深層に最も近い場所で、オブジェクトの寿命を制御できる「強力なツール」だ。
コントロール配列という過去の亡霊に縛られるな。`AddHandler` と `Dispose` の機微を理解し、メモリとCPUの挙動を支配下に置くこと。それこそが、次の10年も稼働し続ける堅牢なシステムを構築するための、唯一の道筋である。
コードに魂を込めよ。そして、動的なUIを完全に掌握せよ。
