Visão geral de eventos anexadosAttached Events Overview

O XAML (Extensible Application Markup Language, linguagem de marcação de aplicativos extensíveis) define um componente de idioma e um tipo de evento chamado evento anexado.Extensible Application Markup Language (XAML) defines a language component and type of event called an attached event. O conceito de um evento anexado permite que você adicione um manipulador para um evento específico a um elemento arbitrário em vez de um elemento que realmente define ou herda o 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. Nesse caso, nem o objeto potencialmente aumentando o evento, nem a instância de tratamento define ou caso contrário, é "proprietário" do evento.In this case, neither the object potentially raising the event nor the destination handling instance defines or otherwise "owns" the event.

Pré-requisitosPrerequisites

Este tópico pressupõe que você leu a visão geral de eventos roteados e visão geral de XAML (WPF).This topic assumes that you have read Routed Events Overview and XAML Overview (WPF).

Sintaxe de evento anexadoAttached Event Syntax

Os eventos anexados têm uma sintaxe XAML e um padrão de codificação que devem ser usados pelo código de backup para suportar o uso do evento anexado.Attached events have a XAML syntax and a coding pattern that must be used by the backing code in order to support the attached event usage.

Na sintaxe XAML, o evento anexado é especificado não apenas pelo nome do evento, mas pelo seu tipo próprio mais o nome do evento, separado por um ponto (.).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 (.). Porque o nome do evento é qualificado com o nome do seu tipo proprietário, a sintaxe de evento anexado permite que qualquer evento anexado a ser anexado a qualquer elemento que pode ser instanciado.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.

Por exemplo, a seguir é a sintaxe XAML NeedsCleaning para anexar um manipulador para um evento anexado personalizado: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"/>

Observe o aqua: prefixo; o prefixo é necessário nesse caso porque o evento anexado é um evento personalizado proveniente de um xmlns personalizado e mapeado.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.

Como o WPF implementa eventos anexadosHow WPF Implements Attached Events

No WPF, os eventos anexados são apoiados por um RoutedEvent campo e são roteados através da árvore depois de serem levantados.In WPF, attached events are backed by a RoutedEvent field and are routed through the tree after they are raised. Normalmente, a origem do evento anexado (o objeto que gera o evento) é uma fonte de sistema ou serviço e o objeto que executa o código que gera o evento não é, portanto, uma parte direta da árvore de elementos.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.

Cenários para eventos anexadosScenarios for Attached Events

No WPF, eventos anexados estão presentes em determinadas áreas de recurso onde há abstração Mouse em Validation nível de serviço, como para os eventos habilitados pela classe estática ou pela classe.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 que interagem com ou usam o serviço podem usar o evento na sintaxe de evento anexado ou eles podem escolher aumentar o evento anexado como um evento roteado que faz parte de como a classe integra os recursos do serviço.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.

Embora o WPF defina uma série de eventos anexados, os cenários em que você usará ou manuseará o evento anexado diretamente são muito limitados.Although WPF defines a number of attached events, the scenarios where you will either use or handle the attached event directly are very limited. Geralmente, o evento anexado serve a um propósito de arquitetura, mas é então encaminhado para um evento roteado de eventos CLR ..Generally, the attached event serves an architecture purpose, but is then forwarded to a non-attached (backed with a CLR event "wrapper") routed event.

Por exemplo, o Mouse.MouseDown evento anexado subjacente pode ser UIElement mais MouseDown facilmente UIElement manipulado em qualquer dado usando isso em vez de lidar com sintaxe de evento anexada em XAML ou código.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. O evento anexado serve um propósito na arquitetura porque permite expansão futura de dispositivos de entrada.The attached event serves a purpose in the architecture because it allows for future expansion of input devices. O dispositivo hipotético Mouse.MouseDown só precisaria aumentar para simular a entrada Mouse do mouse, e não precisaria derivar para fazê-lo.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. No entanto, esse cenário envolve o manuseio de códigos dos eventos, e o manuseio xaml do evento anexado não é relevante para este cenário.However, this scenario involves code handling of the events, and XAML handling of the attached event is not relevant to this scenario.

Tratando um evento anexado no WPFHandling an Attached Event in WPF

O processo para identificar um evento anexado e o código do manipulador que você vai escrever, é basicamente o mesmo para um evento roteado.The process for handling an attached event, and the handler code that you will write, is basically the same as for a routed event.

Em geral, um evento anexado ao WPF não é muito diferente de um evento roteado pelo WPF.In general, a WPF attached event is not very different from a WPF routed event. As diferenças são como o evento é originado e como ele é exposto por uma classe como membro (o que também afeta a sintaxe do manipulador XAML).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).

No entanto, como observado anteriormente, os eventos anexados ao WPF existentes não são particularmente destinados ao manuseio no WPF.However, as noted earlier, the existing WPF attached events are not particularly intended for handling in WPF. Com mais frequência, o objetivo do evento é habilitar um elemento de composição para relatar um estado para um elemento pai na composição, no qual, o evento é gerado normalmente em código e também depende do tratamento da classe na classe pai relevante.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. Por exemplo, espera-se Selector que os itens Selected dentro de um elevam o Selector evento anexado, que Selector é então manipulado SelectionChangedpela classe e, em seguida, potencialmente convertido pela classe em um evento roteado diferente, .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. Para obter mais informações sobre eventos roteados e identificação por classe, consulte Marcando eventos roteados como manipulados e tratamento de classes.For more information on routed events and class handling, see Marking Routed Events as Handled, and Class Handling.

Definir seus próprios eventos anexados como eventos roteadosDefining Your Own Attached Events as Routed Events

Se você está derivando de classes de base comuns do WPF, você pode implementar seus próprios eventos anexados, incluindo certos métodos de padrão em sua classe e usando métodos de utilidade que já estão presentes nas classes base.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.

O padrão é o seguinte:The pattern is as follows:

  • Um método Adicione O Manipulador de Nome deEvento com dois parâmetros.A method AddEventNameHandler with two parameters. O primeiro parâmetro é a instância à qual o manipulador de eventos é adicionado.The first parameter is the instance to which the event handler is added. O segundo parâmetro é o manipulador de eventos a adicionar.The second parameter is the event handler to add. O método public deve staticser e, sem valor de retorno.The method must be public and static, with no return value.

  • Um método Remova o Manipulador de Nome deEvento com dois parâmetros.A method RemoveEventNameHandler with two parameters. O primeiro parâmetro é a instância da qual o manipulador de eventos é removido.The first parameter is the instance from which the event handler is removed. O segundo parâmetro é o manipulador de eventos a remover.The second parameter is the event handler to remove. O método public deve staticser e, sem valor de retorno.The method must be public and static, with no return value.

O método do acessório AddEventNameHandler facilita o processamento xaml quando os atributos do manipulador de eventos anexados são declarados em um elemento.The AddEventNameHandler accessor method facilitates XAML processing when attached event handler attributes are declared on an element. Os métodos 'Adicionar manipulador de nome deevento' e remover o manipulador de nome deevento também permitem o acesso ao código na loja de manipuladores de eventos para o evento anexado.The AddEventNameHandler and RemoveEventNameHandler methods also enable code access to the event handler store for the attached event.

Este padrão geral ainda não é preciso o suficiente para a implementação prática em uma estrutura, porque qualquer determinada implementação de leitor XAML pode ter diferentes esquemas para identificar eventos subjacentes na linguagem de suporte e arquitetura.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. Esta é uma das razões pelas quais a WPF implementa eventos anexados como eventos roteados; o identificador a serRoutedEventusado para um evento ( ) já é definido pelo sistema de eventos WPF.This is one of the reasons that WPF implements attached events as routed events; the identifier to use for an event (RoutedEvent) is already defined by the WPF event system. Além disso, o roteamento de um evento é uma extensão natural de implementação no conceito de nível de linguagem XAML de um evento anexado.Also, routing an event is a natural implementation extension on the XAML language-level concept of an attached event.

A implementação do Manipulador de Nomes deEventos para AddHandler um evento anexado ao WPF consiste em chamar o evento roteado e o manipulador como argumentos.The AddEventNameHandler implementation for a WPF attached event consists of calling the AddHandler with the routed event and handler as arguments.

Essa estratégia de implementação e o sistema de eventos roteados em geral restringem o manuseio de eventos anexados a UIElement classes derivadas ou ContentElement derivadas, pois apenas essas classes possuem AddHandler implementações.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.

Por exemplo, o código NeedsCleaning a seguir define o Aquariumevento anexado na classe proprietário, usando a estratégia de evento anexado do WPF de declarar o evento anexado como um evento roteado.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 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

Observe que o método usado para estabelecer o RegisterRoutedEventcampo identificador de evento anexado é, na verdade, o mesmo método que é usado para registrar um evento roteado não anexado.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. Eventos anexados e eventos roteados são registrados para um repositório centralizado interno.Attached events and routed events all are registered to a centralized internal store. Essa implementação de repositório de eventos permite a consideração conceitual de "eventos como uma interface" que é abordada na visão geral de eventos roteados.This event store implementation enables the "events as an interface" conceptual consideration that is discussed in Routed Events Overview.

Gerar um evento anexado WPFRaising a WPF Attached Event

Você normalmente não precisa levantar eventos anexados definidos pelo WPF existentes a partir do seu código.You do not typically need to raise existing WPF-defined attached events from your code. Esses eventos seguem o modelo conceitual de "serviços" gerais, e as aulas de serviços, como InputManager são responsáveis pela elevação dos eventos.These events follow the general "service" conceptual model, and service classes such as InputManager are responsible for raising the events.

No entanto, se você estiver definindo um evento personalizado com base RoutedEventno modelo RaiseEvent WPF de basear UIElement eventos ContentElementanexados, você pode usar para levantar um evento anexado de qualquer ou .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. Levantar um evento roteado (anexado ou não) requer que você declare um elemento específico na árvore de elementos como a fonte do evento; essa fonte é RaiseEvent relatada como o interlocutor.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. Determinar qual elemento é relatado como a fonte na árvore é responsabilidade do serviçoDetermining which element is reported as the source in the tree is your service's responsibility

Confira tambémSee also