添付イベントの概要Attached Events Overview

Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) は言語コンポーネントと添付イベントと呼ばれている種類のイベントを定義します。defines a language component and type of event called an attached event. 添付イベントという概念を利用すると、イベントを実際に定義または継承する要素にではなく、任意の要素に特定のイベントのハンドラーを追加できます。The concept of an attached event enables you to add a handler for a particular event to an arbitrary element rather than to an element that actually defines or inherits the event. この場合、イベントを発生させる可能性があるオブジェクトとターゲット処理インスタンスのいずれもイベントを定義せず、"所有" しません。In this case, neither the object potentially raising the event nor the destination handling instance defines or otherwise "owns" the event.

必須コンポーネントPrerequisites

このトピックは、「ルーティング イベントの概要」と「XAML の概要 (WPF)」を既に読んでいることを前提としています。This topic assumes that you have read Routed Events Overview and XAML Overview (WPF).

添付イベントの構文Attached Event Syntax

添付イベントには XAMLXAML 構文とコーディング パターンが含まれています。コーディング パターンは、添付イベントの使用をサポートする目的でバッキング コードで使用する必要があります。Attached events have a XAMLXAML syntax and a coding pattern that must be used by the backing code in order to support the attached event usage.

XAMLXAML 構文では、添付イベントはそのイベント名だけでなく、その所有タイプとイベント名により指定されます。所有タイプとイベント名はドット (.) で区切られます。In XAMLXAML syntax, the attached event is specified not just by its event name, but by its owning type plus the event name, separated by a dot (.). イベント名はその所有タイプにより修飾されるため、添付イベントの構文では、インスタンス化できるあらゆる要素に添付イベントを添付できます。Because the event name is qualified with the name of its owning type, the attached event syntax allows any attached event to be attached to any element that can be instantiated.

たとえば、カスタム XAMLXAML 添付イベントのハンドラーを添付する NeedsCleaning 構文は次のようになります。For example, the following is the XAMLXAML syntax for attaching a handler for a custom NeedsCleaning attached event:

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

aqua: 接頭辞に注意してください。この場合は、マッピングされたカスタム xmlns から来ているカスタム イベントが添付イベントであるため、この接頭辞が必要になります。Note the aqua: prefix; the prefix is necessary in this case because the attached event is a custom event that comes from a custom mapped xmlns.

WPF で添付イベントを実装する方法How WPF Implements Attached Events

WPFWPF、添付イベントが支え、RoutedEventフィールドおよび発生後に、ツリーを介してルーティングされます。In WPFWPF, attached events are backed by a RoutedEvent field and are routed through the tree after they are raised. 通常、添付イベントの発生源 (イベントを発生させたオブジェクト) はシステムまたはサービス ソースです。そのため、イベントを発生させるコードを実行するオブジェクトは要素ツリーの直接的一部ではありません。Typically, the source of the attached event (the object that raises the event) is a system or service source, and the object that runs the code that raises the event is therefore not a direct part of the element tree.

添付イベントのシナリオScenarios for Attached Events

WPFWPF、添付イベントは、特定の機能領域に存在する、静的で有効になっているイベントのサービス レベルの抽象化などがMouseクラスまたはValidationクラス。In WPFWPF, attached events are present in certain feature areas where there is service-level abstraction, such as for the events enabled by the static Mouse class or the Validation class. サービスと連動する、またはサービスを利用するクラスは、添付イベント構文のイベントを利用するか、クラスによるサービスの機能統合に含まれるルーティング イベントとして添付イベントを添付できます。Classes that interact with or use the service can either use the event in the attached event syntax, or they can choose to surface the attached event as a routed event that is part of how the class integrates the capabilities of the service.

WPFWPF は添付イベントの数を定義しますが、添付イベントを直接使用または処理するシナリオは非常に限られています。Although WPFWPF defines a number of attached events, the scenarios where you will either use or handle the attached event directly are very limited. 一般的には、添付イベントはアーキテクチャ目的にサービスを提供しますが、その後、非添付の (CLRCLR イベント "ラッパー" でサポートされる) ルーティング イベントに転送されます。Generally, the attached event serves an architecture purpose, but is then forwarded to a non-attached (backed with a CLRCLR event "wrapper") routed event.

たとえば、基になる添付イベントMouse.MouseDownより簡単に処理できる、特定のUIElementを使用してMouseDownUIElementか、添付イベント構文を処理するのではなくでXAMLXAMLまたはコード。For instance, the underlying attached event Mouse.MouseDown can more easily be handled on any given UIElement by using MouseDown on that UIElement rather than dealing with attached event syntax either in XAMLXAML or code. 添付イベントは、入力機器の将来の拡張を可能にするため、アーキテクチャにおける目的にサービスを提供します。The attached event serves a purpose in the architecture because it allows for future expansion of input devices. させる仮定のデバイスのみ必要がありますMouse.MouseDownで、マウスの入力をシミュレートするために順序付けおよびから派生する必要はありませんMouseするようにします。The hypothetical device would only need to raise Mouse.MouseDown in order to simulate mouse input, and would not need to derive from Mouse to do so. ただし、このシナリオでは、イベントのコードが処理されます。添付イベントの XAMLXAML 処理はこのシナリオには関係しません。However, this scenario involves code handling of the events, and XAMLXAML handling of the attached event is not relevant to this scenario.

WPF で添付イベントを処理するHandling an Attached Event in WPF

添付イベントと記述するハンドラー コードを処理するプロセスは基本的にルーティング イベントの場合と同じです。The process for handling an attached event, and the handler code that you will write, is basically the same as for a routed event.

一般的には、WPFWPF 添付イベントは WPFWPF ルーティング イベントとそれほど異なっているわけではありません。In general, a WPFWPF attached event is not very different from a WPFWPF routed event. 違いは、イベントの発生源とメンバーとしてクラスにより公開される方法 (これは XAMLXAML ハンドラー構文にも影響を与えます) です。The differences are how the event is sourced and how it is exposed by a class as a member (which also affects the XAMLXAML handler syntax).

ただし、前述のように、既存の WPFWPF 添付イベントは WPFWPF での取り扱いを特に意図しているわけではありません。However, as noted earlier, the existing WPFWPF attached events are not particularly intended for handling in WPFWPF. 多くの場合、このイベントの目的は、合成中、合成された要素が親要素に状態を報告できるようにすることです。合成においては、イベントは通常、コードで発生します。また、関連する親クラスにおいて、クラスの処理に依存します。More often, the purpose of the event is to enable a composited element to report a state to a parent element in compositing, in which case the event is usually raised in code and also relies on class handling in the relevant parent class. 内のアイテムなど、 Selector 、添付を生成する必要がありますSelectedによって、クラスでは、そのイベントが処理される、Selectorクラスし、で可能性のある変換、Selectorクラス別のルーティング イベントをSelectionChanged.For instance, items within a Selector are expected to raise the attached Selected event, which is then class handled by the Selector class and then potentially converted by the Selector class into a different routed event, SelectionChanged. ルーティング イベントとクラス処理については、「ルーティング イベントの処理済みとしてのマーキング、およびクラス処理」を参照してください。For more information on routed events and class handling, see Marking Routed Events as Handled, and Class Handling.

独自の添付イベントをルーティング イベントとして定義するDefining Your Own Attached Events as Routed Events

共通の WPFWPF 基底クラスから派生させる場合、独自の添付イベントを実装できます。クラスに特定のパターン メソッドを追加し、基底クラスに既に存在するユーティリティ メソッドを使用します。If you are deriving from common WPFWPF base classes, you can implement your own attached events by including certain pattern methods in your class and by using utility methods that are already present on the base classes.

パターンは次のとおりです。The pattern is as follows:

  • メソッド追加EventNameハンドラー 2 つのパラメーターを使用します。A method AddEventNameHandler with two parameters. 最初のパラメーターは、イベント ハンドラーを追加するインスタンスです。The first parameter is the instance to which the event handler is added. The second parameter is the event handler to add.The second parameter is the event handler to add. メソッドである必要がありますpublicstatic、戻り値はありません。The method must be public and static, with no return value.

  • メソッド削除EventNameハンドラー 2 つのパラメーターを使用します。A method RemoveEventNameHandler with two parameters. 最初のパラメーターは、イベント ハンドラーを削除するインスタンスです。The first parameter is the instance from which the event handler is removed. 2 番目のパラメーターは、削除するイベント ハンドラーです。The second parameter is the event handler to remove. メソッドである必要がありますpublicstatic、戻り値はありません。The method must be public and static, with no return value.

追加EventNameハンドラーアクセサー メソッドを容易に、XAMLXAML属性が要素で宣言されたイベント ハンドラーをアタッチするときに処理します。The AddEventNameHandler accessor method facilitates the XAMLXAML processing when attached event handler attributes are declared on an element. 追加EventNameハンドラー削除EventNameハンドラーメソッドでは、コードのイベント ハンドラー ストアへのアクセスも有効にします添付イベント。The AddEventNameHandler and RemoveEventNameHandler methods also enable code access to the event handler store for the attached event.

この一般的パターンには、フレームワークの実用的実装のための十分な精度がありません。サポートする言語とアーキテクチャで基礎イベントを識別する方法に関して、特定の XAMLXAML リーダー実装で異なるスキームが与えられる可能性があるためです。This general pattern is not yet precise enough for practical implementation in a framework, because any given XAMLXAML reader implementation might have different schemes for identifying underlying events in the supporting language and architecture. これは、理由の 1 つをWPFWPFルーティング イベントとして実装がアタッチされているイベントはイベントを使用する識別子 (RoutedEvent) で定義されている、WPFWPFイベント システム。This is one of the reasons that WPFWPF implements attached events as routed events; the identifier to use for an event (RoutedEvent) is already defined by the WPFWPF event system. また、イベントのルーティングは、添付イベントの XAMLXAML 言語レベル概念で自然な実装です。Also, routing an event is a natural implementation extension on the XAMLXAML language-level concept of an attached event.

追加EventNameハンドラーの実装をWPFWPF添付イベントの呼び出し元の構成、AddHandlerルーティング イベントとハンドラーの引数として使用します。The AddEventNameHandler implementation for a WPFWPF attached event consists of calling the AddHandler with the routed event and handler as arguments.

この実装方法と、ルーティング イベント システム制限するか、添付イベントの処理が一般にUIElement派生クラスまたはContentElementクラスだけであるため、クラスを派生AddHandler実装します。This implementation strategy and the routed event system in general restrict handling for attached events to either UIElement derived classes or ContentElement derived classes, because only those classes have AddHandler implementations.

たとえば、次のコードは、添付イベントをルーティング イベントとして宣言する WPFWPF 添付イベント方法を利用し、所有者クラス AquariumNeedsCleaning 添付イベントを定義します。For example, the following code defines the NeedsCleaning attached event on the owner class Aquarium, using the WPFWPF attached event strategy of declaring the attached event as a routed event.

public static readonly RoutedEvent NeedsCleaningEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
public static void AddNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
public static void RemoveNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub
Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub

添付イベント id フィールドを確立するために、メソッドを使用することに注意してください。 RegisterRoutedEvent、実際にメソッドと同じ非添付のルーティング イベントを登録するために使用します。Note that the method used to establish the attached event identifier field, RegisterRoutedEvent, is actually the same method that is used to register a non-attached routed event. 添付イベントとルーティング イベントはすべて、集中管理されている内部ストアに登録されます。Attached events and routed events all are registered to a centralized internal store. このイベント ストア実装により "インターフェイスとしてのイベント" という概念が可能になります。この概念に関する説明は「ルーティング イベントの概要」にあります。This event store implementation enables the "events as an interface" conceptual consideration that is discussed in Routed Events Overview.

WPF 添付イベントを発生させるRaising a WPF Attached Event

通常、WPFWPF 定義の既存の添付イベントはコードから発生させる必要がありません。You do not typically need to raise existing WPFWPF defined attached events from your code. これらのイベントを選択し、一般的な「サービス」概念モデルに従い、サービス クラスなどInputManagerイベントの生成を担当します。These events follow the general "service" conceptual model, and service classes such as InputManager are responsible for raising the events.

ただし、に基づいてカスタム添付イベントを定義するかどうか、WPFWPFベースのモデルでイベントをアタッチするRoutedEvent、使用することができますRaiseEventいずれかから添付イベントを発生させるUIElementまたはContentElementします。However, if you are defining a custom attached event based on the WPFWPF model of basing attached events on RoutedEvent, you can use RaiseEvent to raise an attached event from any UIElement or ContentElement. (添付または非) ルーティング イベントを発生させるには、イベント ソースとして要素ツリー内の特定の要素を宣言することが必要です。そのソースとして報告、RaiseEvent呼び出し元。Raising a routed event (attached or not) requires that you declare a particular element in the element tree as the event source; that source is reported as the RaiseEvent caller. ツリーのソースとして報告される要素を決定することはサービスの担当です。Determining which element is reported as the source in the tree is your service's responsibility

関連項目See also