Compartir a través de


Cómo: Agregar control de clases a un evento enrutado

Los eventos enrutados se pueden controlar mediante controladores de clase o de instancia en cualquier nodo concreto de la ruta. En primer lugar, se invocan los controladores de clase, que las implementaciones de clase pueden utilizar para suprimir eventos del control de instancias o introducir otros comportamientos específicos de eventos en eventos que pertenecen a las clases base. En este ejemplo se muestran dos técnicas estrechamente relacionadas para implementar controladores de clase.

Ejemplo

En este ejemplo se utiliza 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, lo que incluye interceptar los clics con el botón primario del mouse y marcarlos como controlados, antes de invocar a la clase del elemento secundario o a cualquier controlador de instancia.

La clase UIElement expone un método virtual que habilita el control de clases en el evento PreviewMouseLeftButtonDown, simplemente invalidando el evento. Ésta es la manera más simple de implementar el control de clases si este tipo de método virtual está disponible en algún punto de la jerarquía de la clase. En el código siguiente se muestra la implementación de OnPreviewMouseLeftButtonDown en "MyEditContainer", que se deriva de Canvas. La implementación marca el evento como controlado en los argumentos y, a continuación, agrega código para aplicar al elemento de origen un cambio básico visible.

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

Si no hay ningún método virtual disponible en las clases base o para ese método concreto, el control de clases se puede agregar directamente mediante un método de utilidad de la clase EventManager, RegisterClassHandler. Únicamente debe llamarse a este método dentro de la inicialización estática de clases que agregan el control de clases. En este ejemplo se agrega otro controlador para PreviewMouseLeftButtonDown y, en este caso, la clase registrada es la clase personalizada. En contraste, cuando se utilizan métodos virtuales, la clase registrada es, en realidad, la clase base UIElement. En aquellos casos en que tanto las clases base como las subclases registran el control de clases, se invocan primero los controladores subclases. El comportamiento en una aplicación sería: en primer lugar, este controlador mostraría su cuadro de mensaje y, a continuación, se mostraría el cambio visual en el controlador del método virtual.

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

Vea también

Tareas

Cómo: Controlar un evento enrutado

Referencia

EventManager

Conceptos

Marcar eventos enrutados como controlados y control de clases

Información general sobre eventos enrutados