次の方法で共有


チュートリアル: イベントの処理 (Visual Basic)

これは、イベントを操作する方法を示す 2 つのトピックの 2 番目です。 最初のトピック 「チュートリアル: イベントの宣言と発生」では、イベントを宣言および発生させる方法を示します。 このセクションでは、そのチュートリアルのフォームとクラスを使用して、イベントが発生したときに処理する方法を示します。

Widget クラスの例では、従来のイベント処理ステートメントを使用します。 Visual Basic には、イベントを操作するための他の手法が用意されています。 演習として、この例を変更して、 AddHandler ステートメントと Handles ステートメントを使用できます。

Widget クラスの PercentDone イベントを処理するには

  1. 次のコードを Form1に配置します。

    Private WithEvents mWidget As Widget
    Private mblnCancel As Boolean
    

    WithEvents キーワードは、変数mWidgetを使用してオブジェクトのイベントを処理することを指定します。 オブジェクトの種類を指定するには、オブジェクトの作成元となるクラスの名前を指定します。

    変数mWidgetは、WithEvents変数がクラス レベルである必要があるため、Form1で宣言されます。 これは、配置するクラスの種類に関係なく当てはまります。

    変数 mblnCancel は、 LongTask メソッドを取り消すために使用されます。

イベントを処理するコードの記述

WithEventsを使用して変数を宣言するとすぐに、クラスのコード エディターの左側のドロップダウン リストに変数名が表示されます。 mWidgetを選択すると、Widget クラスのイベントが右側のドロップダウン リストに表示されます。 イベントを選択すると、対応するイベント プロシージャが、プレフィックス mWidget とアンダースコアと共に表示されます。 WithEvents変数に関連付けられているすべてのイベント プロシージャには、プレフィックスとして変数名が指定されます。

イベントを処理するには

  1. コード エディターの左側のドロップダウン リストから mWidget を選択します。

  2. 右側のドロップダウン リストから PercentDone イベントを選択します。 コード エディターで、mWidget_PercentDone イベント プロシージャが開きます。

    コード エディターは、新しいイベント ハンドラーを挿入するのに便利ですが、必須ではありません。 このチュートリアルでは、イベント ハンドラーをコードに直接コピーする方が直接的です。

  3. 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 メソッドを使用すると、ラベルを再描画できます。また、ユーザーは [キャンセル] ボタンをクリックできます。

  4. Button2_Click イベント ハンドラーの次のコードを追加します。

    Private Sub Button2_Click(
        ByVal sender As Object,
        ByVal e As System.EventArgs
    ) Handles Button2.Click
        mblnCancel = True
    End Sub
    

LongTaskの実行中にユーザーが [キャンセル] ボタンをクリックした場合、Button2_Click イベントは、DoEvents ステートメントでイベント処理の実行が許可されるとすぐに実行されます。 クラス レベルの変数 mblnCancelTrue に設定され、 mWidget_PercentDone イベントはそれをテストし、 ByRef Cancel 引数を True に設定します。

WithEvents 変数をオブジェクトに接続する

Form1 は、 Widget オブジェクトのイベントを処理するように設定されました。 残っているのは、どこかで Widget を見つけることです。

デザイン時に変数 WithEvents を宣言すると、オブジェクトは関連付けされません。 WithEvents変数は、他のオブジェクト変数と同じです。 オブジェクトを作成し、 WithEvents 変数を使用してオブジェクトへの参照を割り当てる必要があります。

オブジェクトを作成して参照を割り当てるには

  1. コード エディターの左側のドロップダウン リストから (Form1 イベント) を選択します。

  2. 右側のドロップダウン リストから Load イベントを選択します。 コード エディターで、Form1_Load イベント プロシージャが開きます。

  3. Widgetを作成するには、Form1_Load イベント プロシージャの次のコードを追加します。

    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に設定する必要があります。

LongTask は、12.2 秒のタスク期間で呼び出されます。 PercentDone イベントは、1 秒の 3 分の 1 に 1 回発生します。 イベントが発生するたびに、 mWidget_PercentDone イベント プロシージャが実行されます。

LongTaskが完了すると、mblnCancelがテストされ、LongTaskが正常に終了したかどうか、またはmblnCancelTrueに設定されたために停止したかどうかを確認します。 達成率は、前者のケースでのみ更新されます。

プログラムを実行するには

  1. F5 キーを押して、プロジェクトを実行モードにします。

  2. [ タスクの開始 ] ボタンをクリックします。 PercentDone イベントが発生するたびに、完了したタスクの割合でラベルが更新されます。

  3. [ キャンセル ] ボタンをクリックしてタスクを停止します。 クリックしても、[ キャンセル ] ボタンの外観がすぐに変更されないことに注意してください。 Click イベントは、My.Application.DoEvents ステートメントでイベント処理が許可されるまで発生できません。

    My.Application.DoEvents メソッドは、フォームとまったく同じ方法でイベントを処理しません。 たとえば、このチュートリアルでは、[ キャンセル ] ボタンを 2 回クリックする必要があります。 フォームでイベントを直接処理できるようにするには、マルチスレッドを使用できます。 詳細については、「 マネージド スレッド」を参照してください。

F11 でプログラムを実行し、一度に 1 行ずつコードをステップ実行することが有益な場合があります。 実行がLongTaskに入り、PercentDoneイベントが発生するたびにForm1を簡単に再入力する方法を明確に確認できます。

Form1のコードで実行が戻っている間に、LongTask メソッドが再び呼び出された場合はどうなるでしょうか。 最悪の場合、イベントが発生するたびに LongTask が呼び出された場合、スタック オーバーフローが発生する可能性があります。

新しいWidgetへの参照をmWidgetに割り当てることで、変数mWidgetが別のWidget オブジェクトのイベントを処理するようにすることができます。 実際には、ボタンをクリックするたびにこれを行う Button1_Click でコードを作成できます。

別のウィジェットのイベントを処理するには

  • mWidget.LongTask(12.2, 0.33)を読み取る行のすぐ前に、Button1_Click プロシージャに次のコード行を追加します。

    mWidget = New Widget
    ' Create a new Widget object.
    

上記のコードでは、ボタンがクリックされるたびに新しい Widget が作成されます。 LongTask メソッドが完了するとすぐに、Widgetへの参照が解放され、Widgetが破棄されます。

WithEvents変数に含めることができるオブジェクト参照は一度に 1 つだけであるため、別のWidget オブジェクトをmWidgetに割り当てると、前のWidget オブジェクトのイベントは処理されなくなります。 mWidgetが古いWidgetへの参照を含む唯一のオブジェクト変数である場合、オブジェクトは破棄されます。 複数の Widget オブジェクトからのイベントを処理する場合は、 AddHandler ステートメントを使用して各オブジェクトからのイベントを個別に処理します。

WithEvents変数は必要な数まで宣言できますが、WithEvents変数の配列はサポートされていません。

こちらも参照ください