Udostępnij za pośrednictwem


Jak dodać obsługę klas dla wydarzenia routowanego

Zdarzenia kierowane mogą być obsługiwane przez obsługiwacze klasy lub obsługiwacze wystąpień na dowolnym węźle w ścieżce. Procedury obsługi klas są wywoływane jako pierwsze i mogą być używane przez implementacje klas do pomijania zdarzeń z obsługi wystąpień lub wprowadzenia innych zachowań specyficznych dla zdarzeń dotyczących zdarzeń należących do klas bazowych. W tym przykładzie przedstawiono dwie ściśle powiązane techniki implementowania procedur obsługi klas.

Przykład

W tym przykładzie użyto niestandardowej klasy opartej na panelu Canvas. Podstawowym założeniem aplikacji jest to, że klasa niestandardowa wprowadza zachowania na swoich elementach podrzędnych, w tym przechwytywanie kliknięć lewego przycisku myszy i oznaczanie ich jako obsłużonych, przed wywołaniem klasy elementu podrzędnego lub jakiejkolwiek procedury obsługi wystąpień.

Klasa UIElement udostępnia metodę wirtualną, która umożliwia obsługę klas zdarzenia PreviewMouseLeftButtonDown, poprzez po prostu zastąpienie metody obsługi zdarzenia. Jest to najprostszy sposób implementacji obsługi klas, jeśli taka metoda wirtualna jest dostępna gdzieś w hierarchii klasy. Poniższy kod przedstawia implementację OnPreviewMouseLeftButtonDown w "MyEditContainer", która pochodzi z Canvas. Implementacja oznacza zdarzenie jako obsługiwane w argumentach, a następnie dodaje kod, aby nadać elementowi źródłowemu podstawową widoczną zmianę.

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

Jeśli żadna metoda wirtualna nie jest dostępna w klasach bazowych lub dla tej konkretnej metody, obsługę klas można dodać bezpośrednio, korzystając z metody pomocniczej klasy EventManager, RegisterClassHandler. Tę metodę należy wywoływać wyłącznie w trakcie statycznej inicjalizacji klas, które dodają obsługę klas. W tym przykładzie dodano kolejną procedurę obsługi dla PreviewMouseLeftButtonDown , a w tym przypadku zarejestrowana klasa jest klasą niestandardową. Natomiast w przypadku korzystania z maszyn wirtualnych zarejestrowana klasa jest naprawdę klasą podstawową UIElement. W przypadkach, gdy zarówno klasy bazowe, jak i podklasy rejestrują obsługę klas, procedury obsługi podklasy są wywoływane jako pierwsze. W aplikacji takie zachowanie polegałoby na tym, że najpierw procedura obsługi wyświetli okno komunikatu, a następnie ukaże się zmiana wizualna w procedurze obsługi metody wirtualnej.

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

Zobacz też