29

問題は、すべての調査を行った後でも、通常のルーティング イベントと添付イベントの違いを見つけることができないということです。機能的な違いは何ですか?または、他の人は何もないと同意しますか?

実装

ButtonBase クラスは、ClickEvent という名前のルーティング イベントを宣言します。通常のルーティング イベント。

public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));

[Category("Behavior")]
public event RoutedEventHandler Click
{
    add
    {
        base.AddHandler(ClickEvent, value);
    }
    remove
    {
        base.RemoveHandler(ClickEvent, value);
    }
}

Mouse クラスは、MouseDownEvent という名前のルーティング イベントを宣言します。付属のイベント。

public static readonly RoutedEvent MouseDownEvent = EventManager.RegisterRoutedEvent("MouseDown", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(Mouse));

public static void AddMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
    UIElement.AddHandler(element, MouseDownEvent, handler);
}

public static void RemoveMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
    UIElement.RemoveHandler(element, MouseDownEvent, handler);
}

どちらのイベントも EventManager に登録され、パブリック、静的、読み取り専用のフィールドとして同じ方法で保存されます。ClickEvent には、base.AddHandler と base.RemoveHandler をそれぞれ呼び出すカスタムの add アクセサーと remove アクセサーを備えたバッキング CLR イベント フィールドがあります。どちらも、ButtonBase の派生元である UIElement 基本クラスで宣言されています。代わりに、MouseDownEvent には AddMouseDownHandler と RemoveMouseDownHandler の 2 つの静的メソッドがあり、最終的に ClickEvent と同様に UIElement で宣言された同じ 2 つの AddHandler と RemoveHandler メソッドを呼び出します。

静的クラスで宣言された実際の添付イベントの Add*Handler および Remove*Handler 静的メソッドは、特定の命名規則に従って、WPF イベント システムがリフレクションを使用して実行時に適切な追加および削除ハンドラーを見つけられるようにする必要があります。


使用法

どちらのイベントも、次のように XAML でハンドラーをアタッチできます。

<Grid Button.Click="Grid_Click"
      Mouse.MouseDown="Grid_MouseDown">
</Grid>

両方のイベントは、次のコードで添付できます。

// Attach ClickEvent handler.
myGrid.AddHandler(Button.ClickEvent, new RoutedEventHandler(Grid_Click));

// Attach MouseDownEvent handler.
Mouse.AddMouseDownHandler(myGrid, Grid_MouseDown);

ご覧のとおり、どちらのイベントも、それらを所有または宣言していない要素に関連付けることができます。


結論 - 添付イベントとは

MSDN ドキュメントの状態: http://msdn.microsoft.com/en-us/library/bb613550.aspx

Extensible Application Markup Language (XAML) は、言語コンポーネントと、添付イベントと呼ばれるイベントの種類を定義します。添付イベントの概念により、特定のイベントのハンドラーを、実際にイベントを定義または継承する要素ではなく、任意の要素に追加できます。この場合、イベントを発生させる可能性のあるオブジェクトも、宛先処理インスタンスも、イベントを定義または「所有」しません。

さらに、試験 70-511 用の公式 MCTS トレーニング キット - Microsoft .NET Framework 4 を使用した Windows アプリケーション開発には、次のように記載されています。

コントロール自体では発生できないイベントのハンドラーをコントロールで定義することができます。これらのインシデントは、添付イベントと呼ばれます。たとえば、グリッド内のボタン コントロールについて考えてみましょう。Button クラスは Click イベントを定義しますが、Grid クラスは定義しません。ただし、XAML コードで Button コントロールの Click イベントをアタッチすることにより、グリッド内のボタンのハンドラーを定義することもできます。

「添付イベント」という用語は、Microsoft の学習リソース全体であいまいに思われますが、ここでは、添付イベントと XAML 添付イベント構文という 2 つの異なるが非常に密接に関連する概念が使用されていることは明らかです。私が引用した両方の Microsoft ソースは、実際の添付イベントではなく、XAML 添付イベントの構文を参照しているようです。ただし、添付イベントの概要の MSDN ページには、実際の添付イベントを実装する方法が示されていますが、トレーニング キットにはありません。

Mouse.MouseDownEvent は、対応する静的な追加および削除ハンドラーを使用して静的クラスで宣言されたルーティング イベント (添付イベントとも呼ばれます) の例です。ただし、ButtonBase.ClickEvent は通常のルーティング イベントですが、実際の添付イベントと同じ方法で XAML 添付イベント構文で引き続き使用できます。

実際の添付イベントの目的は、開発者が既存の UIElement 派生クラスの新しいルーティング イベントをサブクラス化せずに宣言できるようにすることです。つまり、発生させたり処理したいクラスに実際に存在することなく、新しいルーティング イベントをアタッチすることができます。しかし、ちょっと待ってください... そもそもそれが純粋なルーティング イベントの主な目的ではないでしょうか。

MSDN のルーティング イベントの概要ページ: http://msdn.microsoft.com/en-us/library/ms742806.aspx

機能の定義: ルーティング イベントは、イベントを発生させたオブジェクトだけでなく、要素ツリー内の複数のリスナーでハンドラーを呼び出すことができるイベントの一種です。

その機能定義から、ルーティング イベントは基本的に添付イベントとまったく同じ機能を提供するように見えます。したがって、基本的に添付イベントは、静的クラスでルーティング イベントを宣言するための単なる手段であり、通常のルーティング イベントよりもメリットはありません。

ここで何かが足りないかもしれないので、あなたの考えを教えてください。

ありがとう、ティム・バレンタイン

4

2 に答える 2

5

違いは主に構文であり、両方のデリゲート参照は WPF の EventManager によって処理されますが、添付されたイベントによって提供されるのは、すべてのクラスの実装を肥大化させることなく汎用機能を宣言できることです。

通常のルーティング イベントの場合、クラスは、イベント ハンドラーを呼び出すことによって、ある時点でイベントに応答できるようにするためのインターフェイスを提供します。ただし、WPF が知る必要があるのは、それが特定の型から派生したオブジェクトであるかどうか、およびハンドラーが登録されているかどうかだけです。これは、より単純なクラス階層を作成できることを意味し、Open-Closed Principle (Open to Extension、Closed to Modification) もサポートします。このようにして、プログラマーはいくつかのクラスが持つべき新しい動作を定義できますが、元のクラスを変更する必要はありません。

添付プロパティも参照してください

于 2014-01-23T21:33:50.220 に答える