Cómo: Agregar control de clases a un evento enrutado
Los eventos enrutados se pueden controlar mediante controladores de clase o controladores de instancia en cualquier nodo de la ruta. Los controladores de clase se invocan primero, y las implementaciones de clase pueden usarlos para suprimir eventos del control de instancias o para introducir otros comportamientos específicos de eventos en eventos que pertenecen a clases base. En este ejemplo se muestran dos técnicas estrechamente relacionadas para implementar controladores de clase.
Ejemplo
En este ejemplo se usa una clase personalizada basada en el panel Canvas. La premisa básica de la aplicación es que la clase personalizada introduce comportamientos en sus elementos secundarios (incluido interceptar los clics del botón izquierdo del mouse y marcarlos como controlados) antes de invocar a la clase de elemento secundario o a cualquier controlador de instancia.
La clase UIElement expone un método virtual que permite el control de clases en el evento PreviewMouseLeftButtonDown, simplemente invalidando el evento. Esta es la forma más sencilla de implementar el control de clases si este método virtual está disponible en algún lugar de la jerarquía de la clase. En el código siguiente se muestra la implementación OnPreviewMouseLeftButtonDown en "MyEditContainer" que se deriva de Canvas. La implementación marca el evento como controlado en los argumentos y, después, agrega código para proporcionar al elemento de origen un cambio visible básico.
protected override void OnPreviewMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true; //suppress the click event and other leftmousebuttondown responders
MyEditContainer ec = (MyEditContainer)e.Source;
if (ec.EditState)
{ ec.EditState = false; }
else
{ ec.EditState = true; }
base.OnPreviewMouseRightButtonDown(e);
}
Protected Overrides Sub OnPreviewMouseRightButtonDown(ByVal e As System.Windows.Input.MouseButtonEventArgs)
e.Handled = True 'suppress the click event and other leftmousebuttondown responders
Dim ec As MyEditContainer = CType(e.Source, MyEditContainer)
If ec.EditState Then
ec.EditState = False
Else
ec.EditState = True
End If
MyBase.OnPreviewMouseRightButtonDown(e)
End Sub
Si no hay ningún virtual disponible en las clases base o para ese método en concreto, el control de clases se puede agregar directamente mediante un método de utilidad de la clase EventManager, RegisterClassHandler. Solo se debe llamar a este método dentro de la inicialización estática de las clases que agregan control de clases. En este ejemplo se agrega otro controlador para PreviewMouseLeftButtonDown y, en este caso, la clase registrada es la clase personalizada. En cambio, cuando se usan virtuales, la clase registrada es realmente la clase base UIElement. En los casos en los que tanto las clases base como la subclase registren el control de clases, primero se invocará a los controladores de la subclase. El comportamiento en una aplicación sería, en primer lugar, que este controlador mostraría su cuadro de mensaje y, después, se mostraría el cambio visual en el controlador del método virtual.
static MyEditContainer()
{
EventManager.RegisterClassHandler(typeof(MyEditContainer), PreviewMouseRightButtonDownEvent, new RoutedEventHandler(LocalOnMouseRightButtonDown));
}
internal static void LocalOnMouseRightButtonDown(object sender, RoutedEventArgs e)
{
MessageBox.Show("this is invoked before the On* class handler on UIElement");
//e.Handled = true; //uncommenting this would cause ONLY the subclass' class handler to respond
}
Shared Sub New()
EventManager.RegisterClassHandler(GetType(MyEditContainer), PreviewMouseRightButtonDownEvent, New RoutedEventHandler(AddressOf LocalOnMouseRightButtonDown))
End Sub
Friend Shared Sub LocalOnMouseRightButtonDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
MessageBox.Show("this is invoked before the On* class handler on UIElement")
'e.Handled = True //uncommenting this would cause ONLY the subclass' class handler to respond
End Sub
Vea también
.NET Desktop feedback