連載

プロフェッショナルVB.NETプログラミング

第25回 イベントとイベント・ハンドラ

(株)ピーデー
川俣 晶
2002/11/16

Page1 Page2 Page3

イベントの発生源を識別する

 1つのイベント・ハンドラで、複数のイベントを受け取る場合、イベント・ハンドラ内で、発生源のコントロールを識別したい場合がある。その際には、イベント・ハンドラのメソッドの第1引数(ByVal sender As System.Object)を利用できる。この引数には、イベントの発生源となったコントロールのインスタンスへの参照が入っている。これを調べれば、発生源を区別するのは容易である。また区別できるだけでなく、そのインスタンスを操作することもできる。以下は上記のサンプル・プログラム2に、そのような機能を追加したものである。

  1: Public Class Form1
  2:   Inherits System.Windows.Forms.Form
  3:
  4: …Windows フォーム デザイナで生成されたコード…
  5:
  6:   Private Sub ClickHandler(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
  7:     If sender Is Button1 Then
  8:       MsgBox("Button1 Clicked!")
  9:     ElseIf sender Is Button2 Then
 10:       MsgBox("Button2 Clicked!")
 11:     ElseIf sender Is Button3 Then
 12:       MsgBox("Button3 Clicked!")
 13:     End If
 14:     Dim btn As Button = sender
 15:     btn.Text = "Clicked!"
 16:   End Sub
 17: End Class
押されたボタンのインスタンスを操作するサンプル・プログラム3

 これを実行すると以下のようになる。

サンプル・プログラム3の実行結果

 ここで最も左のボタンを押すと以下のメッセージ・ボックスが表示される。

サンプル・プログラム3の実行結果で、[Button1]ボタンを押した場合に表示されるメッセージ・ボックス

 メッセージ・ボックスを閉じると以下のようにボタン上の文字列が変化する。

メッセージ・ボックスを閉じると、押したボタン上の文字列が変化する

 このソースのポイントは2つある。1つは、7行目などで見られるように、If文で発生源のインスタンスがどれかを判定すること。これは、引数senderに発生源のインスタンスへの参照が入っていると分かれば難しいことではないだろう。もう1つは、14〜15行目に見られるように、引数senderを適切なデータ型(ここではButtonクラス)に変換してから、Textプロパティにアクセスしていることである。このコードは、どのボタンが押された場合でも、押されたボタンのTextプロパティを書き換えることになる。

イベントの付加情報を得る

 実際にVB.NETでイベントを扱い始めると、おや? と思うことに出会う。例えば、VB 6(Visual Basic 6.0)では、MouseMoveイベントにはX As Single、Y As Singleといったマウスポインタの位置などの引数が存在するのに、VB.NETでMouseMoveイベントを作成しても、XやYという引数が見当たらないのである。

 例えばVB 6の場合は、マウス・ポインタの位置などを利用するプログラムは以下のようになる。まずフォーム上にラベルを2つ貼り付けた後で、以下のようなコードを入力する。

 1: Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
 2:   Label1.Caption = X & "," & Y
 3:   Label2.Caption = Button
 4: End Sub
マウスの座標とボタンの状態を表示するVB 6のサンプル・プログラム4(VB 6でフォームに2つのラベルを貼り付けておく必要あり)

 これを実行すると以下のようになる。

サンプル・プログラム4の実行結果

 上はマウスポインタの座標値、下がボタンの状況を示す数値である(「1」は左ボタンのみが押されている状態)。

 では、これとほぼ同等のプログラムをVB.NETで作成してみよう。同じように、フォーム上にラベルを2つ貼り付けてから、以下のようにコードを編集する。

  1: Public Class Form1
  2:   Inherits System.Windows.Forms.Form
  3:
  4: …Windows フォーム デザイナで生成されたコード…
  5:
  6:   Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
  7:     Label1.Text = e.X & "," & e.Y
  8:     Label2.Text = e.Button.ToString()
  9:   End Sub
 10: End Class
サンプル・プログラム4と同等のVB.NETのサンプル・プログラム5(VB.NETでフォームに2つのラベルを貼り付けておく必要あり)

 これを実行すると以下のようになる。

サンプル・プログラム5の実行結果

 上はマウスポインタの座標値、下がボタンの状況を示す値である。座標系のデフォルトが異なっているので、数値はVB 6と桁が1つ違っている。ボタン値は、文字列に変換された状態で出力されており、VB 6のように数値ではない。

 さて、プログラム・コードを見てみよう。ここでのポイントは、6行目のForm1_MouseMoveメソッドの第2引数である。イベント・ハンドラのメソッドの第2引数は、System.EventArgsクラスまたはそれを継承したクラスのみを指定することができる。特に付加情報のないClickイベントなどは、基本となるSystem.EventArgsクラスにしておけば問題はない。だが、付加情報がある場合は、付加情報を含むクラスをSystem.EventArgsクラスを継承して作成し、引数として渡すことができる。例えばMouseMoveイベントの場合、そのようにして用意されたSystem.Windows.Forms.MouseEventArgsクラスがそれにあたる。このクラスは、System.EventArgsクラスを継承していて、イベント・ハンドラの第2引数に使用できると同時に、マウスイベントに固有の情報を表現する能力を持っている。ここでは、マウスポインタの座標値であるX、Yや、マウスボタンの状態を保持するButtonなどが使われている。

 このような例から見て分かるとおり、イベント・ハンドラのメソッドは、どんなタイプのイベントであろうと、常に引数の数は2つである。もし、何か付加的な値が必要とされる場合は、第2引数のクラスを継承して拡張し、その中に入れて受け渡すようになっている。VB 6に慣れていると、引数に必要な値が見あたらず、焦ってしまうことがあるかもしれないが、このような仕様に変化しているので、慌てないように注意していただきたい。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第25回 イベントとイベント・ハンドラ
    1.イベントを処理する
  2.イベントの発生源を識別する
    3.自家製のイベント
 
「プロフェッショナルVB.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間