チュートリアル: イベントの処理 (Visual Basic)
これは、イベントの処理方法について説明した 2 つのトピックのうちの 2 番目にあたります。 1 番目のトピックである「チュートリアル: イベントの宣言と発生」では、イベントを宣言し、発生させる方法について説明しました。 このセクションでは、そのチュートリアルのフォームとクラスを使用して、イベントの発生時にそれらを処理する方法を示します。
Widget
クラスの例では、従来のイベント処理ステートメントを使用しています。 Visual Basic には、別のイベント処理手法も用意されています。 演習として、この例を変更し、AddHandler
ステートメントと Handles
ステートメントを使用してみましょう。
Widget クラスの PercentDone イベントを処理するには
Form1
に次のコードを挿入します。Private WithEvents mWidget As Widget Private mblnCancel As Boolean
WithEvents
キーワードにより、オブジェクトのイベントの処理に変数mWidget
が使用されるように指定しています。 オブジェクトの種類は、オブジェクトの作成元にするクラスの名前を記載することで指定します。WithEvents
変数はクラスレベルである必要があるため、変数mWidget
はForm1
内で宣言します。 これは、挿入先のクラスの型に左右されません。変数
mblnCancel
は、LongTask
メソッドを取り消すためのものです。
イベントを処理するコードの作成
WithEvents
を使用して変数を宣言すると、このクラスのコード エディターの左側にあるドロップダウン リストに、その変数の名前が表示されます。 mWidget
を選択すると、右側のドロップダウン リストに Widget
クラスのイベントが表示されます。 イベントを選択すると、対応するイベント プロシージャが、接頭辞 mWidget
とアンダースコア付きで表示されます。 WithEvents
変数に関連するすべてのイベント プロシージャに、変数名が接頭辞として付与されます。
イベントを処理するには
コード エディターの左側のドロップダウン リストで、[
mWidget
] を選択します。右側のドロップダウン リストで
PercentDone
イベントを選択します。 コード エディターにmWidget_PercentDone
イベント プロシージャが表示されます。Note
新しいイベント ハンドラーを挿入する場合、コード エディターは便利ですが、使用は必須ではありません。 今回のチュートリアルでは、コードにイベント ハンドラーを直接コピーする方が簡単です。
mWidget_PercentDone
イベント ハンドラーに次のコードを追加します。Private Sub mWidget_PercentDone( ByVal Percent As Single, ByRef Cancel As Boolean ) Handles mWidget.PercentDone lblPercentDone.Text = CInt(100 * Percent) & "%" My.Application.DoEvents() If mblnCancel Then Cancel = True End Sub
PercentDone
イベントが発生するたびに、イベント プロシージャによりLabel
コントロールに完了率が表示されます。DoEvents
メソッドによって、ラベルの再描画を許可すると同時に、 [キャンセル] ボタンをクリックする機会をユーザーに提供しています。Button2_Click
イベント ハンドラーに次のコードを追加します。Private Sub Button2_Click( ByVal sender As Object, ByVal e As System.EventArgs ) Handles Button2.Click mblnCancel = True End Sub
LongTask
の実行中にユーザーが [キャンセル] ボタンをクリックすると、DoEvents
ステートメントによりイベント処理の実行が許可されしだい、Button2_Click
イベントが実行されます。 クラスレベルの変数 mblnCancel
が True
に設定された後、mWidget_PercentDone
イベントによりテストが行われ、ByRef Cancel
引数が True
に設定されます。
オブジェクトへの WithEvents 変数の接続
これで、Widget
オブジェクトのイベントを処理するように Form1
を設定できました。 あとは、Widget
を見つけるだけです。
デザイン時に変数 WithEvents
を宣言しても、変数にオブジェクトは関連付けられません。 WithEvents
変数は、単に他のオブジェクト変数と似たものです。 オブジェクトを作成してから、そのオブジェクトに対する参照を WithEvents
変数に割り当てる必要があります。
オブジェクトを作成して参照を割り当てるには
コード エディターの左側のドロップダウン リストで、 [(Form1 イベント)] を選択します。
右側のドロップダウン リストで
Load
イベントを選択します。 コード エディターにForm1_Load
イベント プロシージャが表示されます。Form1_Load
イベント プロシージャに、Widget
を作成する次のコードを追加します。Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs ) Handles MyBase.Load mWidget = New Widget End Sub
このコードを実行すると、Visual Basic により Widget
オブジェクトが作成され、そのイベントが mWidget
に関連付けられているイベント プロシージャと接続されます。 この時点以降、Widget
で PercentDone
イベントが発生するたびに、mWidget_PercentDone
イベント プロシージャが実行されます。
LongTask メソッドを呼び出すには
Button1_Click
イベント ハンドラーに次のコードを追加します。Private Sub Button1_Click( ByVal sender As Object, ByVal e As System.EventArgs ) Handles Button1.Click mblnCancel = False lblPercentDone.Text = "0%" lblPercentDone.Refresh() mWidget.LongTask(12.2, 0.33) If Not mblnCancel Then lblPercentDone.Text = CStr(100) & "%" End Sub
LongTask
メソッドを呼び出す前に、完了率を示すラベルを初期化する必要があります。また、メソッド取り消し用のクラスレベルの Boolean
フラグを False
に設定する必要があります。
タスクの実行時間を 12.2 秒に指定したうえで、LongTask
が呼び出されています。 PercentDone
イベントは 3 分の 1 秒ごとに発生します。 イベントが発生するたびに、mWidget_PercentDone
イベント プロシージャが実行されます。
LongTask
が完了すると mblnCancel
がテストされ、LongTask
が正常に完了したか、または mblnCancel
が True
に設定されていたために中止されたかどうかが確認されます。 完了率は、前者の場合にのみ更新されます。
プログラムを実行するには
F5 キーを押して、プロジェクトを実行モードに切り替えます。
[タスクの開始] をクリックします。
PercentDone
イベントが発生するたびにラベルが更新され、完了したタスクの割合が示されます。タスクを停止するには、 [キャンセル] ボタンをクリックします。 [キャンセル] ボタンの外観は、クリックしてもすぐには変わらないことに注意してください。
Click
イベントは、My.Application.DoEvents
ステートメントでイベント処理が許可されるまで発生しません。Note
My.Application.DoEvents
メソッドがイベントを処理する方法は、フォームによる方法とは一部異なります。 たとえば、このチュートリアルでは、 [キャンセル] ボタンを 2 回クリックする必要があります。 フォームでイベントを直接処理できるようにするには、マルチスレッドを使用します。 詳細については、「マネージド スレッド処理」を参照してください。
F11 キーを使用してプログラムを実行し、コードを一度に 1 行ずつステップ実行することをお勧めします。 LongTask
の実行が開始された後、PercentDone
イベントが発生するたびに Form1
が一時的に再度開始されるようすを明確に確認できます。
Form1
のコードが再実行されている間に、LongTask
メソッドが再び呼び出されたらどうなるでしょうか。 イベント発生時に毎回 LongTask
が呼び出されると、最悪の場合スタック オーバーフローが発生する可能性があります。
変数 mWidget
に新しい Widget
オブジェクトへの参照を割り当てることで、別の Widget
のイベントを mWidget
で処理できます。 実際には、ボタンをクリックするたびに、Button1_Click
のコードでこの処理を実行可能です。
別のウィジェットのイベントを処理するには
Button1_Click
プロシージャのmWidget.LongTask(12.2, 0.33)
という行のすぐ下に、次のコード行を追加します。mWidget = New Widget ' Create a new Widget object.
上記のコードでは、ボタンがクリックされるたびに新しい Widget
を作成します。 LongTask
メソッドが完了するとすぐに Widget
への参照が解放され、Widget
が破棄されます。
WithEvents
変数に含められるオブジェクト参照は一度に 1 つだけです。そのため、別の Widget
オブジェクトを mWidget
に割り当てると、前の Widget
オブジェクトのイベントは処理されなくなります。 古い Widget
への参照を含むオブジェクト変数が mWidget
のみである場合、オブジェクトは破棄されます。 複数の Widget
オブジェクトのイベントを処理する場合は、AddHandler
ステートメントを使用して、各オブジェクトのイベントを個別に処理します。
Note
WithEvents
変数は必要な数だけ宣言できますが、WithEvents
変数の配列はサポートされません。
関連項目
.NET