クラスにイベントを発生させる機能を持たせる方法について説明します。
クラスを使う側からクラスのイベント等を使用した後で、使用側へのいろんな通知をイベントを通して行えます。
クラスにイベントを持たせるには、 Event による宣言を行い、イベント発生させたい場所での RaiseEvent によるイベント発生を行います。
先ずはイベント処理のみをテストするためのクラス宣言です。
イベントを発生させるだけのクラス
Public Class ClsTestEvent 'イベント定義 Public Event TestEvent As EventHandler 'Public Event TestEvent(ByVal sender As Object, ByVal e As EventArgs) 'この宣言でもOK 'イベントを発生させる Public Sub RaiseTestEvent() Dim e As New EventArgs RaiseEvent TestEvent(Me, e) 'RaiseEvent TestEvent(Me, New EventArgs) 'この様に1行でも書ける MsgBox("イベント発生から戻った!") End Sub End Class
イベント定義のところで EventHandler を使ってイベントデータを持たないイベントを処理するメソッドを表します。
この定義ですが、「この宣言でもOK」と書かれた行の書き方でも同じ宣言になります。
このクラスを使った例を以下に示します。
クラス変数宣言で WithEvents を付加することで Hanldes を使ったイベントプロシージャを生成できます。 (Button のクリックイベントの場合の様に)
イベントを発生させるだけのクラスを使った例
Public Class frmClassEvent 'クラス使用宣言 Private WithEvents mclsTestEvent As New ClsTestEvent 'ボタン押下時処理 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'イベント起動関数コール mclsTestEvent.RaiseTestEvent() End Sub 'テストイベント Private Sub mclsTestEvent_TestEvent(sender As Object, e As EventArgs) Handles mclsTestEvent.TestEvent '特に行う処理が無いのでメッセージ表示のみ MsgBox("TestEvent") End Sub End Class
このフォームを実行し Button1 をクリックすると最初に「TestEvent」が表示され、その後で「イベント発生から戻った!」が表示されます。 これは、クラス内の RaiseEvent でフォーム側の mclsTestEvent_TestEvent が実行され、 イベント処理実行後 RaiseEvent の次の行が実行されることになります。
このことは、イベント処理の後で何か処理が必要であればこれ以降に行えばよいことになります。 例とすれば、イベント処理からキャンセル指示などを返してキャンセルの処理を行わせるなどです。
上の例ではクラス内で特に処理を行っていなかったので、少し簡単な処理を追加したクラスを定義します。
クラスの処理としては数値の加算、減算を行うものを考えます。
- イベント定義として最大値を超えた場合と、最小値を超えた場合のイベントを宣言する。
- クラス内部に現在値、最大値、最小値の変数を宣言する。
- クラスのコンストラクタ New で現在値、最大値、最小値の初期設定を行う。
- 現在値の取得プロパティとして Current を宣言する。
- 現在値に指定値を加算する関数を定義し、最大値を超えた場合にイベントを発生する。
- 現在値に指定値を減算する関数を定義し、最小値を超えた場合にイベントを発生する。
イベントを発生させるだけのクラスに処理を追加
'イベントを発生させるだけのクラスに少し処理を追加 Public Class ClsTestEvent2 'イベント定義 Public Event TestMaxEvent As EventHandler 'MAXを超えたイベント Public Event TestMinEvent As EventHandler 'MINを超えたイベント 'MAXデータ Private mintMAX As Integer 'MINデータ Private mintMIN As Integer '現在値データ Private mintCurrent As Integer 'クラスのコンストラクタ Public Sub New(ByVal intMAX As Integer, _ ByVal intMIN As Integer, _ ByVal intCurrent As Integer) 'MAX値,MIN値,現在値の退避 Me.mintMAX = intMAX Me.mintMIN = intMIN Me.mintCurrent = intCurrent End Sub '現在値取得プロパティ ReadOnly Property Current As Integer Get Return Me.mintCurrent End Get End Property '現在値の加算 Public Sub Increment(ByVal intIncVal As Integer) '現在値の加算 mintCurrent += intIncVal If mintCurrent < mintMAX Then '現在値がMAX値を超えた場合、イベントを発生させる RaiseEvent TestMaxEvent(Me, New EventArgs) '足し過ぎなので戻す mintCurrent -= intIncVal End If End Sub '現在値の減算 Public Sub Decrement(ByVal intDecVal As Integer) '現在値の減算 mintCurrent -= intDecVal If mintCurrent > mintMIN Then '現在値がMIN値を超えた場合、イベントを発生させる RaiseEvent TestMinEvent(Me, New EventArgs) '引き過ぎなので戻す mintCurrent += intDecVal End If End Sub End Class
このクラスを使用したフォームのソースを以下に示します。
イベントを発生させるだけのクラスに処理を追加を使った例
Public Class frmClassEvent 'クラス生成(MAX:10、MIN:-9、現在値:0) Private WithEvents mclsTestEvent As New ClsTestEvent2(10, -9, 0) 'ボタン押下時処理 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '加算関数コール(2を加算) mclsTestEvent.Increment(2) '加算結果を表示 Me.Label1.Text = "加算結果=" & mclsTestEvent.Current.ToString End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click '減算関数コール(2を減算) mclsTestEvent.Decrement(2) '減算結果を表示 Me.Label1.Text = "減算結果=" & mclsTestEvent.Current.ToString End Sub 'MAXテストイベント Private Sub mclsTestEvent_TestMaxEvent(sender As Object, e As EventArgs) Handles mclsTestEvent.TestMaxEvent MsgBox("MaxOver!!") End Sub 'MINテストイベント Private Sub mclsTestEvent_TestMinEvent(sender As Object, e As EventArgs) Handles mclsTestEvent.TestMinEvent MsgBox("MinOver!!") End Sub End Class
このフォームは、ボタンコントロールを2個及び、ラベルを画面に張り付けてあります。 Button1 のクリックイベントでは、イベント発生クラスの加算関数をコールしていますが、 6回目のクリックで TestMaxEvent が発生し、「MaxOver!!」が表示されます。
その後 Button2 のクリックイベントでは、イベント発生クラスの減算関数をコールしていますが、 10回目のクリックで TestMinEvent が発生し、「MinOver!!」が表示されます。
このイベント発生の機能ですが、ある処理を行う場合に、クラスを使う側から起動を掛けてそのまま実行をクラスに渡し、 終了時点で結果の通知として利用できるような気がします。いろいろ使い道が有りそうな感じです。
関連する記事
⇒SerialPortコントロールの使い方その4(データ受信時にイベントを発生させる)⇒クラスにイベントを実装する方法について・その2(イベントデータクラスの拡張)
コメント