c# - wpf controls
Eventos adjuntos de WPF frente a eventos no adjuntos (1)
La pregunta es que después de toda mi investigación, todavía no puedo encontrar la diferencia entre un evento enrutado regular y un evento adjunto. ¿Cuál es la función de la diferencia? o ¿otros aceptan que no hay ninguno?
Implementación
La clase ButtonBase declara un evento enrutado llamado ClickEvent; un evento enrutado normal.
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));
[Category("Behavior")]
public event RoutedEventHandler Click
{
add
{
base.AddHandler(ClickEvent, value);
}
remove
{
base.RemoveHandler(ClickEvent, value);
}
}
La clase Mouse declara un evento enrutado denominado MouseDownEvent; un evento adjunto.
public static readonly RoutedEvent MouseDownEvent = EventManager.RegisterRoutedEvent("MouseDown", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(Mouse));
public static void AddMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
UIElement.AddHandler(element, MouseDownEvent, handler);
}
public static void RemoveMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
UIElement.RemoveHandler(element, MouseDownEvent, handler);
}
Ambos eventos se registran con EventManager y se almacenan como campos públicos, estáticos y de solo lectura de la misma manera. ClickEvent tiene un campo de evento CLR de respaldo con accesos de acceso y eliminación personalizados que llaman a base.AddHandler y base.RemoveHandler respectivamente; ambos están declarados en la clase base UIElement de la que se deriva ButtonBase. MouseDownEvent en cambio tiene dos métodos estáticos AddMouseDownHandler y RemoveMouseDownHandler, que finalmente llaman a los mismos dos métodos AddHandler y RemoveHandler declarados en UIElement como ClickEvent.
Los métodos estáticos Add * Handler y Remove * Handler para los eventos reales conectados declarados en una clase estática deben seguir una convención de nomenclatura específica para permitir que el sistema de eventos de WPF use la reflexión para encontrar el complemento apropiado y eliminar manejadores en tiempo de ejecución.
Uso
Ambos eventos pueden tener manejadores conectados en XAML de la siguiente manera:
<Grid Button.Click="Grid_Click"
Mouse.MouseDown="Grid_MouseDown">
</Grid>
Ambos eventos se pueden adjuntar en el código de la siguiente manera:
// Attach ClickEvent handler.
myGrid.AddHandler(Button.ClickEvent, new RoutedEventHandler(Grid_Click));
// Attach MouseDownEvent handler.
Mouse.AddMouseDownHandler(myGrid, Grid_MouseDown);
Como puede ver, ambos eventos se pueden adjuntar a elementos que no son de su propiedad o no pueden declararlos.
Conclusión - ¿Qué es un evento adjunto?
Estados de documentación de MSDN: http://msdn.microsoft.com/en-us/library/bb613550.aspx
El Lenguaje de marcado de aplicaciones extensible (XAML) define un componente de idioma y un tipo de evento llamado evento adjunto. El concepto de evento adjunto le permite agregar un controlador para un evento en particular a un elemento arbitrario en lugar de un elemento que realmente define o hereda el evento. En este caso, ni el objeto que potencialmente genera el evento ni la instancia de manejo de destino definen o de otro modo "poseen" el evento.
Además, el kit de capacitación MCTS oficial para el examen 70-511 - Desarrollo de aplicaciones de Windows con Microsoft .NET Framework 4 establece:
Es posible que un control defina un controlador para un evento que el control no puede elevar por sí mismo. Estos incidentes se llaman eventos adjuntos. Por ejemplo, considere los controles de botón en una grilla. La clase Button define un evento Click, pero la clase Grid no. Sin embargo, aún puede definir un controlador para botones en la cuadrícula adjuntando el evento Click del control Button en el código XAML.
El término "evento adjunto" parece ser borroso a través de los recursos de aprendizaje de Microsoft, aunque está claro que hay dos conceptos diferentes pero muy relacionados en juego aquí: eventos adjuntos y sintaxis del evento adjunto XAML. Ambas fuentes de Microsoft que he citado parecen referirse a la sintaxis del evento adjunto XAML, en lugar de los eventos adjuntos reales. Sin embargo, la página de resumen de eventos adjuntos de MSDN continúa para mostrarle cómo implementar un evento adjunto real, mientras que el kit de capacitación no lo hace.
Mouse.MouseDownEvent es un ejemplo de un evento enrutado declarado en una clase estática con los correspondientes controladores de eliminación y eliminación estáticos, también conocido como un evento adjunto. Sin embargo, ButtonBase.ClickEvent es un evento enrutado normal, aunque todavía se puede usar con la sintaxis de eventos adjuntos XAML de la misma manera que un evento adjunto real.
El propósito de un evento adjunto real es que permite a los desarrolladores declarar nuevos eventos enrutados para las clases existentes derivadas de UIE sin tener que subclasificarlas; lo que significa que puedes adjuntar nuevos eventos enrutados sin que realmente existan en las clases que deseas subir o manejarlos. Pero, espere un minuto ... ¿no es ese el objetivo principal de un evento enrutado puro en primer lugar?
La página de resumen de eventos enrutados en los estados de MSDN: http://msdn.microsoft.com/en-us/library/ms742806.aspx
Definición funcional: un evento enrutado es un tipo de evento que puede invocar manejadores en múltiples oyentes en un árbol de elementos, en lugar de solo en el objeto que generó el evento.
A partir de esa definición funcional, parece que cualquier evento enrutado proporciona esencialmente la misma funcionalidad exacta que un evento adjunto. Así que, básicamente, un evento adjunto es realmente solo un medio para declarar un evento enrutado en una clase estática y realmente no ofrece ningún beneficio sobre los eventos enrutados normales.
Déjame saber que piensas, ya que me puede estar perdiendo algo aquí.
Gracias, Tim Valentine
La diferencia es principalmente sintáctica, ambas referencias delegadas están siendo manejadas por el EventManager de WPF, pero lo que los eventos adjuntos te dan es la capacidad de declarar funcionalidades genéricas sin necesidad de inflar la implementación de todas las clases.
En el caso de un evento enrutado normal, la clase proporciona la interfaz para poder, en algún momento, responder a un evento llamando al controlador de eventos. Pero todo lo que WPF necesita saber es si se trata de un objeto derivado de un tipo dado y si un controlador fue registrado. Esto significa que podemos hacer jerarquías de clase más simples y también es compatible con el principio de Open-Closed (Abierto a la extensión, cerrado a la modificación). De esta forma, un programador puede definir un nuevo comportamiento que varias clases deberían tener, pero que no necesita modificar las clases originales.
Ver también Propiedades adjuntas