フォーム上のコントロールへのイベント処理を宣言する場合には AddHandler メソッドを使うことを以下の記事で紹介しました。
⇒コントロールの同じイベント処理に複数の関連付けをテスト:[AddHandler,DirectCast]
この記事の中で、各イベントの処理を1個の関数で処理できることを示しましたが、そのなかでは同じ処理を行っていました。 今回はこの関数の中でそれぞれのコントロールに対して内部で処理を分けることで、 同じコントロールのイベント関数としては入口は1個ですが、別々の処理を記述できます。 これはコントロールを配列で処理する方法の逆のアプローチになると思います。
⇒コントロールを配列で処理する方法 :[AddHandler,DirectCast]
今回のソースでは KeyPress イベント用関数を追加し、テキストボックスコントロールのそのイベントに関連付けます。 KeyPress イベント用関数のなかでは、どのテキストボックスから呼ばれたのかを判別する為、 呼び出し元オブジェクトの sender の名前 name を使って場合分けします。
今後、テキストボックスが増えた場合にはこの判定と、その処理を追加することになります。
フォーム上のコントロールのイベント処理の一括関連付けその2
Public Class frmAddHandler2 ' フォームロードイベント Private Sub frmAddHandler_Load(sender As Object, e As EventArgs) Handles Me.Load 'コントロールへのイベントハンドラ関連付け Call Me.SetEvent(Me.Controls) 'フォームがすべてのキー イベントを受け取る Me.KeyPreview = True End Sub ' コントロールへのイベントハンドラ関連付け ' param CtrlColl :コントロールコレクション Private Sub SetEvent(ByVal CtrlColl As Control.ControlCollection) 'コントロール変数 Dim objControl As Control 'テキストボックスコントロール変数 Dim objTextBox As TextBox 'コントロールがある分だけループ For Each objControl In CtrlColl If TypeOf objControl Is TextBox Then 'テキストボックスコントロールに変換 objTextBox = DirectCast(objControl, TextBox) 'Enterイベントの関連付け AddHandler objTextBox.Enter, AddressOf CtrlEnterEvent 'Changedイベントの関連付け AddHandler objTextBox.TextChanged, AddressOf CtrlTextChangedEvent 'KeyPressイベントの関連付け AddHandler objTextBox.KeyPress, AddressOf CtrlTextKeyPressEvent Else End If Next End Sub ' コントロールのEnterイベント処理 Private Sub CtrlEnterEvent(ByVal sender As Object, ByVal e As System.EventArgs) If TypeOf sender Is TextBox Then 'TextBoxのとき DirectCast(sender, TextBox).SelectAll() End If End Sub ' コントロールのTextChangedイベント処理 Private Sub CtrlTextChangedEvent(ByVal sender As Object, ByVal e As System.EventArgs) If TypeOf sender Is TextBox Then 'TextBoxのとき Dim objTextBox As TextBox = DirectCast(sender, TextBox) '仮の処理として表示内容をTagに退避 objTextBox.Tag = objTextBox.Text End If End Sub ' コントロールのKeyPressイベント処理(1カ所で集中管理する) Private Sub CtrlTextKeyPressEvent(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) 'コントロールの名前により処理を分ける Select Case sender.name Case "TextBox1" '[TextBox1]は数字のみ入力とする If Not ("0" <= e.KeyChar And e.KeyChar <= "9") Then e.Handled = True End If Case "TextBox2" '[TextBox2]は英字大文字の A ~ Z のみ入力とする If Not ("A" <= e.KeyChar And e.KeyChar <= "Z") Then e.Handled = True End If Case "TextBox3" '[TextBox3]は英字子文字の a ~ z のみ入力とする If Not ("a" <= e.KeyChar And e.KeyChar <= "z") Then e.Handled = True End If End Select End Sub ' フォームKeyDownイベント Private Sub frmEnterNext_KeyDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown If e.KeyCode = Keys.Enter Then If e.Control = False Then '[Enter]キーで次の TabIndex があるコントロールへフォーカスを移す Me.SelectNextControl(Me.ActiveControl, Not e.Shift, True, True, True) End If End If End Sub ' フォームKeyPressイベント Private Sub frmEnterNext_KeyPress(ByVal sender As Object, _ ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress If e.KeyChar = ControlChars.Cr Then '[Enter]キーで音が出るので、キーイベントが処理されたことにして音を消す e.Handled = True End If End Sub End Class
これを実行すると以下の様に TextBox1 には数字のみ TextBox2 には英大文字("A"~"Z")のみ TextBox3 には英子文字("a"~"z")のみ、の入力ができます。
今回の方法は、とにかく同じコントロールの同じイベント処理を1個の関数で集中的に処理したい場合には有効だと思います。 テキストボックスのそれぞれのイベントで記述すれば同じじゃないかという突っ込みはあると思いますが...
コメント