Compartilhar via


Visão geral sobre eventos anexados

Extensible Application Markup Language (XAML)define um componente de idioma e o tipo de evento chamado um anexado evento. 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.

Este tópico contém as seguintes seções.

  • Prerequisites
  • Attached Event Syntax
  • How WPF Implements Attached Events
  • Scenarios for Attached Events
  • Handling an Attached Event in WPF
  • Defining Your Own Attached Events as Routed Events
  • Raising a WPF Attached Event
  • Tópicos relacionados

Prerequisites

This topic assumes that you have read Visão geral sobre eventos roteados and Visão geral do XAML (WPF).

Attached Event Syntax

Eventos anexados têm um XAML sintaxe e um padrão de codificação que deve ser usado pelo código de apoio para suportar o uso de evento anexado.

In XAML 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.

For example, the following is the XAML syntax for attaching a handler for a custom NeedsCleaning attached event:

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

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.

How WPF Implements Attached Events

In WPF, 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

In WPF, 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.

Although WPF defines a number of attached events, the scenarios where you will either use or handle the attached event directly are very limited. Generally, the attached event serves an architecture purpose, but is then forwarded to a non-attached (backed with a CLR event "wrapper") routed event.

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 XAML or code. The attached event serves a purpose in the architecture because it allows for future expansion of input devices. O dispositivo hipotético só precisa elevar Mouse.MouseDown em ordem para simular a entrada do mouse e não seria necessário derivar de Mouse para fazer o SO. However, this scenario involves code handling of the events, and XAML handling of the attached event is not relevant to this scenario.

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.

In general, a WPF attached event is not very different from a WPF routed event. The differences are how the event is sourced and how it is exposed by a class as a member (which also affects the XAML handler syntax).

However, as noted earlier, the existing WPF attached events are not particularly intended for handling in WPF. 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. 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 Marcando Eventos Roteados como Manipulados e Manipulação de Classes.

Defining Your Own Attached Events as Routed Events

If you are deriving from common WPF 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:

  • A method Add*Handler with two parameters. The first parameter must identify the event, and the identified event must match names with the * in the method name. O segundo parâmetro é o manipulador para adicionar. The method must be public and static, with no return value.

  • A method Remove*Handler with two parameters. The first parameter must identify the event, and the identified event must match names with the * in the method name. The second parameter is the handler to remove. The method must be public and static, with no return value.

The Add*Handler accessor method facilitates the XAML processing when attached event handler attributes are declared on an element. The Add*Handler and Remove*Handler methods also enable code access to the event handler store for the attached event.

This general pattern is not yet precise enough for practical implementation in a framework, because any given XAML reader implementation might have different schemes for identifying underlying events in the supporting language and architecture. Este é um dos motivos que WPF implementa anexado eventos como eventos roteados; o identificador a ser usado para um evento (RoutedEvent) já está definido pela WPF sistema de eventos. Also, routing an event is a natural implementation extension on the XAML language-level concept of an attached event.

O Add*Handler a implementação de um WPF evento anexado consiste de chamada a AddHandler com o evento roteado e manipulador como argumentos.

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.

For example, the following code defines the NeedsCleaning attached event on the owner class Aquarium, using the WPF attached event strategy of declaring the attached event as a routed event.

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
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);
    }
}

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 Visão geral sobre eventos roteados.

Raising a WPF Attached Event

You do not typically need to raise existing WPF defined attached events from your code. These events follow the general "service" conceptual model, and service classes such as InputManager are responsible for raising the events.

However, if you are defining a custom attached event based on the WPF model of basing attached events on RoutedEvent, you can use RaiseEvent to raise an attached event from any UIElement or ContentElement. Elevar um evento roteado (conectado ou não) requer que você declare um determinado elemento na árvore de elementos, como a fonte de evento; Essa fonte é relatada como o RaiseEvent chamador. Determining which element is reported as the source in the tree is your service's responsibility

Consulte também

Conceitos

Visão geral sobre eventos roteados

Sintaxe XAML em detalhes

Classes de personalizadas para WPF e XAML