Gewusst wie: Hinzufügen einer Klassenbehandlung für ein Routingereignis

Weitergeleitete Ereignisse können entweder durch Klassenhandler oder Instanzhandler auf jedem angegebenen Knoten in der Route behandelt werden. Klassenhandler werden zuerst aufgerufen und können von Klassenimplementierungen verwendet werden, um Ereignisse aus der Instanzbehandlung zu unterdrücken oder andere ereignisspezifische Verhaltensweisen bei Ereignissen einzuführen, die Basisklassen gehören. In diesem Beispiel werden zwei eng verwandte Methoden für die Implementierung von Klassenhandlern veranschaulicht.

Beispiel

In diesem Beispiel wird eine benutzerdefinierte Klasse basierend auf dem Canvas-Fenster verwendet. Die grundlegende Prämisse der Anwendung besteht darin, dass die benutzerdefinierte Klasse Verhalten bei ihren untergeordneten Elementen einführt, einschließlich des Abfangens alle linken Maustastenklicks und der Markierung dieser als behandelt, bevor die untergeordnete Elementklasse oder jegliche Instanzhandler dafür aufgerufen werden.

Die UIElement-Klasse stellt eine virtuelle Methode zur Verfügung, die die Klassenbehandlung für das PreviewMouseLeftButtonDown-Ereignis ermöglicht, indem das Ereignis einfach außer Kraft gesetzt wird. Dies ist die einfachste Möglichkeit zum Implementieren der Klassenbehandlung, wenn eine solche virtuelle Methode irgendwo in der Hierarchie Ihrer Klasse verfügbar ist. Der folgende Code zeigt die OnPreviewMouseLeftButtonDown-Implementierung im „MyEditContainer“, der von Canvas abgeleitet wird. Die Implementierung markiert das Ereignis in den Argumenten als behandelt und fügt dann Code hinzu, um das Quellelement grundlegend sichtbar zu verändern.

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

Wenn für Basisklassen oder für diese bestimmte Methode keine virtuelle Methode verfügbar ist, kann die Klassenbehandlung direkt mithilfe einer Hilfsmethode der EventManager-Klasse (RegisterClassHandler) hinzugefügt werden. Diese Methode sollte nur innerhalb der statischen Initialisierung von Klassen aufgerufen werden, die die Klassenbehandlung hinzufügen. In diesem Beispiel wird ein weiterer Handler für PreviewMouseLeftButtonDown hinzugefügt, wobei in diesem Fall die registrierte Klasse die benutzerdefinierte Klasse ist. Im Gegensatz dazu ist die registrierte Klasse bei Verwendung der virtuellen Methoden tatsächlich die UIElement-Basisklasse. In Fällen, in denen Basisklassen und die Unterklasse jeweils die Klassenbehandlung registrieren, werden die Unterklassenhandler zuerst aufgerufen. Das Verhalten in einer Anwendung wäre, dass zuerst dieser Handler sein Meldungsfeld anzeigt und dann die visuelle Änderung im Handler der virtuellen Methode angezeigt wird.

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

Weitere Informationen