Visual Basic と WPF のイベント処理 (WPF .NET)

Visual Basic .NET でコーディングする場合は、言語固有の Handles キーワードを使用して、イベント ハンドラーをオブジェクトにアタッチできます。 オブジェクトには、分離コード内のインスタンスまたは Extensible Application Markup Language (XAML) 内の要素を指定できます。 Handles は、共通言語ランタイム (CLR) イベントまたは Windows Presentation Foundation (WPF) ルーティング イベントのイベント ハンドラーを割り当てるために使用できます。 ただし、ルーティング イベントのイベント ハンドラーをアタッチするために Handles を使用する場合は、いくつかの使用制限があります。

重要

.NET 7 と .NET 6 用のデスクトップ ガイド ドキュメントは作成中です。

前提条件

この記事では、ルーティング イベントの基本的な知識があり、「ルーティング イベントの概要」をお読みになったことを前提としています。 この記事の例について理解するには、Extensible Application Markup Language (XAML) を使い慣れていて、Windows Presentation Foundation (WPF) アプリケーションの記述方法を理解していると役に立ちます。

構文

Handles キーワードを使用する Sub 宣言の構文は、Sub <procedure name> Handles <object name>.<event name> です。 この構文では、<event name> によって指定されたイベントが <object name> によって指定されたオブジェクトで発生したときに実行されるイベント ハンドラーとしてプロシージャを指定します。 イベントは、オブジェクトのクラスまたは基底クラスのメンバーである必要があります。 次の例では、Handles を使用してイベント ハンドラーを XAML 要素にアタッチする方法を示します。

' Click event handler attached to XamlButton using Handles.
Private Sub XamlButton_Click(sender As Object, e As RoutedEventArgs) Handles XamlButton.Click

    ' Handler logic.
    Debug.WriteLine($"Click event handler attached to XamlButton using Handles.")

End Sub

分離コードで定義されているオブジェクトで Handles を使用するには、通常、WithEvents キーワードを使用してオブジェクトを宣言します。 WithEvents の使用方法の詳細については、を参照してください。 WPF では、すべての XAML 要素が Friend WithEvents を使用して自動的に宣言されます。 次の例では、WithEvents を使用して分離コードで定義されるオブジェクトを宣言する方法を示します。

' Declare a new button using WithEvents.
Dim WithEvents CodeButton As New Button With {
    .Content = "New button",
    .Background = Brushes.Yellow
}

' Click event handler attached to CodeButton using Handles.
Private Sub CodeButton_Click(sender As Object, e As RoutedEventArgs) Handles CodeButton.Click

    ' Handler logic.
    Debug.WriteLine($"Click event handler attached to CodeButton using Handles.")

End Sub

複数のイベントに同じハンドラーを使用するには、<object name>.<event name> イベントをコンマ区切りで指定します。 たとえば、Sub Button_Click(sender As Object, e As RoutedEventArgs) Handles Button1.Click, Button2.Click のようにします。 コンマ区切りのイベントの順序は重要ではありません。

複数の Handles ステートメントを使用して、同じイベントに対して異なるハンドラーを割り当てることができます。 Handles ステートメントの順序によって、イベントが発生したときにハンドラーが呼び出される順序が決まることはありません。

ヒント

Handles を使用して追加されたハンドラーを削除するには、RemoveHandler を呼び出します。 たとえば、RemoveHandler Button1.Click, AddressOf Button1_Click のようにします。

WPF アプリケーションでの "ハンドル" の使用

XAML で定義されているオブジェクトの場合、Handles イベント構文 <object name>.<event name> では、オブジェクトを表す XAML 要素に Name または x:Name プロパティが必要です。 ただし、名前 Me を使用できる XAML ページのルート要素には名前プロパティは必要ありません。 次の例では、Handles を使用してイベント ハンドラーを XAML ページのルートにアタッチする方法を示します。

' Loaded event handler attached to the XAML page root using Handles.
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

    ' Handler logic.
    Debug.WriteLine($"Loaded event handler attached to Window using Handles.")

End Sub

XAML ページがコンパイルされると、Name または x:Name パラメーターを持つすべての XAML 要素が Friend WithEvents として宣言されます。 その結果、任意の XAML 要素に Handles を使用できます。

ヒント

Visual Studio IntelliSense では、Handles と共に使用できるオブジェクトが表示されます。

イベント ハンドラーをアタッチするために、Handles、XAML 属性構文、AddHandler ステートメント、または AddHandler メソッドのどれを使用するかに関係なく、イベント システムの動作は同じです。

注意

XAML 属性と Handles の両方を使用して、同じイベント ハンドラーを同じイベントにアタッチしないでください。それ以外の場合、イベント ハンドラーはイベントごとに 2 回呼び出されます。

制限事項

Handles キーワードには、次の使用制限があります。

  • イベントがオブジェクトのクラスまたは基底クラスのメンバーである場合にのみ、イベント ハンドラーをオブジェクトにアタッチするために Handles を使用できます。 たとえば、ButtonBase 基本クラスが Click ルーティング イベントを発生させるボタンに Click イベント ハンドラーをアタッチするために Handles を使用できます。 ただし、ルーティング イベントの特徴の 1 つは、要素ツリーを検査し、イベントを発生させた要素よりも高いレベルで Click イベントをリッスンして処理できる点です。 親要素がリッスンして処理するルーティング イベントは、"添付イベント" と呼ばれます。 Handles は、添付イベントには使用できません。その構文では、イベントを発生させた要素とは異なるリスナーを XAML 要素ツリーで指定することはできないためです。 添付イベントのイベント ハンドラーを割り当てるには、XAML 属性構文または AddHandler メソッドを使用する必要があります。 添付イベントの詳細については、「添付イベントの概要」および「WPF の添付イベント」を参照してください。

  • Handles 構文では、Handled イベントのイベント ハンドラー呼び出しはサポートされていません。 Handled イベントに対してイベント ハンドラーを呼び出せるようにするには、AddHandler(RoutedEvent, Delegate, Boolean) メソッドを使用してイベント ハンドラーをアタッチし、handledEventsToo パラメーターを true に設定します。

参照