更新 : 2007 年 11 月
ルーティング イベントは、クラス ハンドラまたはルート内の特定のノードにあるインスタンスで処理できます。クラス ハンドラが最初に呼び出され、このクラス ハンドラをクラス実装が使用してインスタンス処理からのイベントの出力を抑制したり、基本クラスが所有するイベントに他のイベント固有の動作を導入できます。次の例では、クラス ハンドラを実装するための、非常に密接に関連する 2 つの手法を示します。
使用例
この例では、Canvas パネルに基づくカスタム クラスを使用します。子要素クラスまたはその上にあるインスタンス ハンドラが呼び出される前に、左のマウス ボタンのすべてのクリックをインターセプトし、それらを処理済みとしてマークするなど、カスタム クラスがその子要素に動作を導入していることが、アプリケーションの基本前提になります。
UIElement クラスは、PreviewMouseLeftButtonDown イベントを単純にオーバーライドして、そのイベントでクラス処理を有効にする仮想メソッドを公開します。これは、仮想メソッドがクラスの階層内のどこかで使用できる場合の、最も単純なクラス処理の実装方法です。次のコードは、Canvas から派生した "MyEditContainer" での OnPreviewMouseLeftButtonDown の実装を示します。この実装では、引数でイベントを処理済みとしてマークしてから、ソース要素に基本的な表示変更を与えるコードを追加します。
protected override void OnPreviewMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true; //suppress the click event and other leftmousebuttondown responders
MyEditContainer ec = (MyEditContainer)e.Source;
if (ec.EditState)
{ ec.EditState = false; }
else
{ ec.EditState = true; }
base.OnPreviewMouseRightButtonDown(e);
}
基本クラスまたはその特定のメソッドに対して仮想メソッドが使用できない場合、クラス処理は EventManager クラスのユーティリティ メソッド RegisterClassHandler を使用して直接追加できます。このメソッドは、クラス処理を追加しているクラスの静的な初期化内でのみ呼び出す必要があります。この例では、PreviewMouseLeftButtonDown の別のハンドラを追加します。この場合、登録済みのクラスがカスタム クラスになります。これに対し、仮想メソッドを使用している場合は、登録済みのクラスは実際に UIElement の基本クラスになります。基本クラスとサブクラスがそれぞれクラス処理を登録している場合、サブクラスのハンドラが最初に呼び出されます。この場合のアプリケーションの動作は、まずこのハンドラにそのメッセージ ボックスが表示されてから、仮想メソッドのハンドラのビジュアルな変更が示されます。
static MyEditContainer()
{
EventManager.RegisterClassHandler(typeof(MyEditContainer), PreviewMouseRightButtonDownEvent, new RoutedEventHandler(LocalOnMouseRightButtonDown));
}
internal static void LocalOnMouseRightButtonDown(object sender, RoutedEventArgs e)
{
MessageBox.Show("this is invoked before the On* class handler on UIElement");
//e.Handled = true; //uncommenting this would cause ONLY the subclass' class handler to respond
}
参照
処理手順
概念
ルーティング イベントの処理済みとしてのマーキング、およびクラス処理