Información general sobre eventos adjuntosAttached Events Overview

Lenguaje XAML (Extensible Application Markup Language)Extensible Application Markup Language (XAML) define un componente de lenguaje y un tipo de evento denominado evento adjunto.defines a language component and type of event called an attached event. El concepto de un evento adjunto permite agregar un controlador de un evento determinado a un elemento arbitrario, en lugar de agregarlo a un elemento que realmente define o hereda el 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. En este caso, ni el objeto que genera potencialmente el evento ni la instancia de control del destino definen ni "poseen" de otro modo el evento.In this case, neither the object potentially raising the event nor the destination handling instance defines or otherwise "owns" the event.

Requisitos previosPrerequisites

En este tema se da por supuesto que ha leído Información general sobre eventos enrutados e Información general sobre XAML (WPF).This topic assumes that you have read Routed Events Overview and XAML Overview (WPF).

Sintaxis de los eventos adjuntosAttached Event Syntax

Los eventos adjuntos tienen un modelo de codificación y una sintaxis XAMLXAML que el código de respaldo debe usar para admitir el uso de eventos adjuntos.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.

En la sintaxis XAMLXAML, se especifica el evento adjunto no solo por su nombre de evento, sino por su tipo de propiedad y el nombre de evento, separados por un punto (.).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 (.). Dado que el nombre del evento está calificado con el nombre de su tipo de propiedad, la sintaxis del evento adjunto permite que cualquier evento adjunto se adjunte a cualquier elemento del que se pueda crear una instancia.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 ejemplo, la siguiente es la sintaxis de XAMLXAML para adjuntar un controlador a un evento adjunto NeedsCleaning personalizado: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"/>

Observe el prefijo aqua:, que, en este caso, es necesario porque el evento adjunto es un evento personalizado que procede de un atributo xmlns asignado personalizado.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.

Cómo implementa WPF los eventos adjuntosHow WPF Implements Attached Events

En WPFWPF, adjunta los eventos están respaldados por un RoutedEvent campo y se enrutan a través del árbol después de generarse.In WPFWPF, attached events are backed by a RoutedEvent field and are routed through the tree after they are raised. Normalmente, el origen del evento adjunto (el objeto que genera el evento) es un origen del sistema o del servicio y, por tanto, el objeto que ejecuta el código que genera el evento no forma parte directamente del árbol 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.

Escenarios de eventos adjuntosScenarios for Attached Events

En WPFWPF, adjunta los eventos están presentes en determinadas áreas de características donde hay abstracción de nivel de servicio, como para los eventos que habilita la estática Mouse clase o el Validation clase.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. Las clases que interactúan con el servicio o lo usan pueden emplear el evento de la sintaxis del evento adjunto, o bien pueden optar por exponer el evento adjunto como un evento enrutado que forme parte de cómo la clase integra las capacidades del servicio.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.

Aunque WPFWPF define varios eventos adjuntos, los escenarios donde usará o controlará el evento adjunto directamente son muy limitados.Although WPFWPF defines a number of attached events, the scenarios where you will either use or handle the attached event directly are very limited. Generalmente, el evento adjunto cumple un propósito de arquitectura, pero se reenvía posteriormente a un evento enrutado no adjunto (respaldado por un "contenedor" de eventos de 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.

Por ejemplo, subyacente evento adjunto Mouse.MouseDown más fácilmente se pueden controlar en cualquier UIElement utilizando MouseDown en que UIElement en lugar de tratar con la sintaxis del evento adjunto, ya sea en XAMLXAML o 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 XAMLXAML or code. El evento adjunto cumple un propósito de la arquitectura porque permite la expansión futura de los dispositivos de entrada.The attached event serves a purpose in the architecture because it allows for future expansion of input devices. El dispositivo hipotético solo tendría que generar Mouse.MouseDown para simular la entrada del mouse y no necesitaría derivar Mouse para hacerlo.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 obstante, este escenario implica el control de código de los eventos, y el control de XAMLXAML del evento adjunto no es importante para este escenario.However, this scenario involves code handling of the events, and XAMLXAML handling of the attached event is not relevant to this scenario.

Control de un evento adjunto en WPFHandling an Attached Event in WPF

El proceso para controlar un evento adjunto y el código del controlador que se va a escribir son, básicamente, los mismos que para un evento enrutado.The process for handling an attached event, and the handler code that you will write, is basically the same as for a routed event.

En general, un evento adjunto de WPFWPF no es muy diferente de un evento enrutado de WPFWPF.In general, a WPFWPF attached event is not very different from a WPFWPF routed event. Las diferencias se encuentran en cómo se origina el evento y en cómo lo expone una clase como un miembro (lo que también afecta a la sintaxis del controlador 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).

Sin embargo, como se indicó anteriormente, los eventos adjuntos de WPFWPF existentes no están diseñados especialmente para el control en WPFWPF.However, as noted earlier, the existing WPFWPF attached events are not particularly intended for handling in WPFWPF. Más a menudo, el propósito del evento es habilitar un elemento compuesto para notificar un estado a un elemento primario en la composición, en cuyo caso el evento se genera normalmente en el código y también se basa en el control de clases de la clase primaria pertinente.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 ejemplo, los elementos de un Selector se espera que genere el archivo adjunto Selected controlando el evento, que es, a continuación, la clase el Selector clase y, a continuación, convierte potencialmente por la Selector clase en un evento enrutado diferente, 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. Para obtener más información, consulte Marcar eventos enrutados como controlados y control de clases.For more information on routed events and class handling, see Marking Routed Events as Handled, and Class Handling.

Definición de eventos adjuntos propios como eventos enrutadosDefining Your Own Attached Events as Routed Events

Si realiza la derivación de clases base de WPFWPF comunes, puede implementar sus propios eventos adjuntos incluyendo determinados métodos de patrón en la clase y usando métodos de utilidad que ya están presentes en las clases base.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.

El patrón es el siguiente:The pattern is as follows:

  • Un método agregarEventNamecontrolador con dos parámetros.A method AddEventNameHandler with two parameters. El primer parámetro es la instancia a la que se agrega el controlador de eventos.The first parameter is the instance to which the event handler is added. El segundo parámetro es el controlador de eventos para agregar.The second parameter is the event handler to add. El método debe ser public y static, sin ningún valor devuelto.The method must be public and static, with no return value.

  • Un método quitarEventNamecontrolador con dos parámetros.A method RemoveEventNameHandler with two parameters. El primer parámetro es la instancia desde la que se quita el controlador de eventos.The first parameter is the instance from which the event handler is removed. El segundo parámetro es el controlador de eventos para quitar.The second parameter is the event handler to remove. El método debe ser public y static, sin ningún valor devuelto.The method must be public and static, with no return value.

El agregarEventNamecontrolador facilita el método de descriptor de acceso del XAMLXAML procesos cuando adjunta el controlador de eventos, los atributos se declaran en un elemento.The AddEventNameHandler accessor method facilitates the XAMLXAML processing when attached event handler attributes are declared on an element. El agregarEventNamecontrolador y quitarEventNamecontrolador métodos también habilitar el acceso de código para el almacén del controlador de eventos para el evento adjunto.The AddEventNameHandler and RemoveEventNameHandler methods also enable code access to the event handler store for the attached event.

Este patrón general no es aún lo suficientemente preciso para la implementación práctica en un marco, ya que cualquier implementación determinada del lector de XAMLXAML puede tener esquemas diferentes para identificar eventos subyacentes en el lenguaje y la arquitectura secundarios.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. Esta es una de las razones que WPFWPF implementa adjuntada eventos como eventos enrutados; el identificador que se utiliza para un evento (RoutedEvent) ya está definido por el WPFWPF sistema de eventos.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. Además, el enrutamiento de un evento es una extensión natural de la implementación en el concepto de nivel de lenguaje de XAMLXAML de un evento adjunto.Also, routing an event is a natural implementation extension on the XAMLXAML language-level concept of an attached event.

El agregarEventNamecontrolador implementación para un WPFWPF evento adjunto consiste en llamar a la AddHandler con el evento enrutado y el controlador como argumentos.The AddEventNameHandler implementation for a WPFWPF attached event consists of calling the AddHandler with the routed event and handler as arguments.

Esta estrategia de implementación y el sistema de eventos enrutados en general restringen el control de eventos adjuntos como UIElement las clases derivadas o ContentElement clases derivadas, porque solo esas clases tienen AddHandler implementaciones.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 ejemplo, el código siguiente define el evento adjunto de NeedsCleaning en la clase propietaria Aquarium, mediante la estrategia de declarar un evento adjunto como un evento enrutado que ofrecen los eventos adjuntos de WPFWPF.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

Tenga en cuenta que el método usado para establecer el campo de identificador de evento adjunto, RegisterRoutedEvent, es realmente el mismo método que se usa para registrar un evento enrutado no adjunto.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. Todos los eventos adjuntos y eventos enrutados se registran en un almacén interno centralizado.Attached events and routed events all are registered to a centralized internal store. Esta implementación del almacén de eventos permite la consideración conceptual de "eventos como una interfaz" que se describe en Información general sobre eventos enrutados.This event store implementation enables the "events as an interface" conceptual consideration that is discussed in Routed Events Overview.

Generación de un evento adjunto de WPFRaising a WPF Attached Event

Normalmente, no es necesario generar eventos adjuntos definidos de WPFWPF a partir del código.You do not typically need to raise existing WPFWPF defined attached events from your code. Estos eventos siguen el modelo conceptual general "servicio" así como las clases del servicio InputManager son responsables de generar los eventos.These events follow the general "service" conceptual model, and service classes such as InputManager are responsible for raising the events.

Sin embargo, si va a definir un evento adjunto personalizado basado en la WPFWPF modelo de basar los eventos adjuntos en RoutedEvent, puede usar RaiseEvent para generar un evento adjunto desde cualquier UIElement o 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. Generar un evento enrutado (adjunto o no) requiere que se declare un elemento determinado en el árbol de elementos como el origen del evento; se notifica ese origen como el RaiseEvent llamador.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 qué elemento se notifica como el origen del árbol es responsabilidad del servicio.Determining which element is reported as the source in the tree is your service's responsibility

Vea tambiénSee also