Como adicionar tratamento de classes para um evento roteado

Eventos roteados podem ser manipulados por manipuladores de classe ou de instância em qualquer nó da rota. Manipuladores de classe são invocados primeiro e podem ser usados pelas implementações de classe para suprimir eventos da manipulação de instâncias ou apresentar outros comportamentos específicos de evento em eventos pertencentes a classes base. Este exemplo ilustra duas técnicas intimamente relacionadas para implementar manipuladores de classe.

Exemplo

Este exemplo usa uma classe personalizada com base no Canvas painel. A premissa básica do aplicativo é que a classe personalizada apresenta comportamentos nos seus elementos filho, incluindo a interceptação de cliques com o botão esquerdo do mouse e a marcação deles como manipulados, antes que a classe de elementos filho ou os manipuladores de instância dela sejam invocados.

A UIElement classe expõe um método virtual que permite a manipulação de PreviewMouseLeftButtonDown classe no evento, simplesmente substituindo o evento. Essa será a maneira mais simples de implementar a manipulação de classes se tal método virtual estiver disponível em algum lugar na hierarquia da classe. O código a seguir mostra a OnPreviewMouseLeftButtonDown implementação no "MyEditContainer" que é derivado de Canvas. A implementação marca o evento como manipulado nos argumentos e adiciona algum código para dar ao elemento de origem uma alteração visível básica.

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

Se nenhum virtual estiver disponível nas classes base ou para esse método específico, a manipulação de classes poderá ser adicionada diretamente usando um método utilitário da EventManager classe, RegisterClassHandler. Este método só deve ser chamado dentro da inicialização estática de classes que estão adicionando a manipulação de classes. Este exemplo adiciona outro manipulador para PreviewMouseLeftButtonDown , e, nesse caso, a classe registrada é a classe personalizada. Em contraste, ao usar os virtuais, a classe registrada é realmente a UIElement classe base. Em casos em que as classes base e subclasses registram tratamento de classe, os manipuladores de subclasse são invocados primeiro. O comportamento em um aplicativo seria que primeiro esse manipulador mostraria sua caixa de mensagem e, em seguida, a alteração visual no manipulador do método virtual seria mostrada.

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

Confira também