Omówienie dołączonych zdarzeń (WPF .NET)
Rozszerzalny język znaczników aplikacji (XAML) definiuje składnik języka i typ zdarzenia nazywany dołączonym zdarzeniem. Dołączone zdarzenia mogą służyć do definiowania nowego zdarzenia kierowanego w klasie innej niż element i zgłaszania tego zdarzenia na dowolnym elemenie w drzewie. W tym celu należy zarejestrować dołączone zdarzenie jako zdarzenie kierowane i podać konkretny kod kopii zapasowej , który obsługuje dołączone funkcje zdarzeń. Ponieważ dołączone zdarzenia są rejestrowane jako zdarzenia kierowane, gdy są wywoływane na elemecie, są propagowane przez drzewo elementów.
Ważne
Dokumentacja przewodnika po pulpicie dla platform .NET 6 i .NET 5 (w tym .NET Core 3.1) jest w trakcie budowy.
Wymagania wstępne
W tym artykule przyjęto założenie, że podstawowa wiedza na temat zdarzeń kierowanych Windows Presentation Foundation (WPF) i że przeczytano omówienie zdarzeń trasowanych i XAML w WPF. Aby postępować zgodnie z przykładami w tym artykule, warto zapoznać się z językiem XAML i wiedzieć, jak pisać aplikacje WPF.
Dołączona składnia zdarzeń
W składni XAML dołączone zdarzenie jest określane przez nazwę zdarzenia i jego typ właściciela w postaci <owner type>.<event name>. Ponieważ nazwa zdarzenia jest kwalifikowana przy użyciu nazwy jego typu właściciela, składnia umożliwia dołączanie zdarzenia do dowolnego elementu, który można utworzyć. Ta składnia ma również zastosowanie do procedur obsługi zwykłych zdarzeń kierowanych, które dołączają do dowolnego elementu wzdłuż trasy zdarzenia.
Następująca składnia atrybutów XAML dołącza procedurę AquariumFilter_Clean obsługi dołączonego AquariumFilter.Clean zdarzenia do aquarium1 elementu:
<aqua:Aquarium x:Name="aquarium1" Height="300" Width="400" aqua:AquariumFilter.Clean="AquariumFilter_Clean"/>
W tym przykładzie prefiks jest niezbędny, aqua: ponieważ AquariumFilter klasy i Aquarium istnieją w innej przestrzeni nazw środowiska uruchomieniowego języka wspólnego (CLR) i zestawie.
Można również dołączyć programy obsługi dla dołączonych zdarzeń w kodzie za nim. W tym celu wywołaj metodę AddHandler w obiekcie, do którego program obsługi powinien dołączyć i przekazać identyfikator zdarzenia i program obsługi jako parametry do metody.
Jak WPF implementuje dołączone zdarzenia
Zdarzenia dołączone do platformy WPF są implementowane jako zdarzenia kierowane wspierane przez RoutedEvent pole. W rezultacie dołączone zdarzenia są propagowane przez drzewo elementów po ich podniesieniu. Ogólnie rzecz biorąc, obiekt, który zgłasza dołączone zdarzenie, znane jako źródło zdarzeń, jest systemem lub źródłem usługi. Źródła systemu lub usługi nie są bezpośrednią częścią drzewa elementów. W przypadku innych dołączonych zdarzeń źródło zdarzeń może być elementem w drzewie, takim jak składnik w kontrolce złożonej.
Dołączone scenariusze zdarzeń
W środowisku WPF dołączone zdarzenia są używane w niektórych obszarach funkcji, w których istnieje abstrakcja na poziomie usługi. Na przykład WPF wykorzystuje dołączone zdarzenia włączone przez statyczne Mouse lub Validation klasy. Klasy, które wchodzą w interakcję z usługą lub korzystają z niej, mogą wchodzić w interakcje ze zdarzeniem przy użyciu dołączonej składni zdarzeń lub udostępniać dołączone zdarzenie jako zdarzenie kierowane. Druga opcja jest częścią tego, jak klasa może zintegrować możliwości usługi.
System wejściowy WPF intensywnie używa dołączonych zdarzeń. Jednak prawie wszystkie dołączone zdarzenia są wyświetlane jako równoważne nieprzyłączone zdarzenia kierowane przez elementy podstawowe. Każde zdarzenie wejściowe kierowane jest elementem członkowskim klasy podstawowego elementu i jest obsługiwane za pomocą zdarzenia CLR "otoka". Rzadko będziesz używać dołączonych zdarzeń lub obsługiwać je bezpośrednio. Na przykład łatwiej jest obsłużyć bazowe dołączone Mouse.MouseDown zdarzenie za UIElement pośrednictwem równoważnego UIElement.MouseDown zdarzenia kierowanego niż przy użyciu dołączonej składni zdarzeń w języku XAML lub kod-behind.
Dołączone zdarzenia służą do celów architektury, umożliwiając przyszłe rozszerzanie urządzeń wejściowych. Na przykład nowe urządzenie wejściowe będzie musiało podnieść Mouse.MouseDown tylko w celu symulowania danych wejściowych myszy i nie trzeba z niego korzystać Mouse . Ten scenariusz obejmuje obsługę kodu zdarzenia, ponieważ obsługa kodu XAML dołączonego zdarzenia nie byłaby odpowiednia.
Obsługa dołączonego zdarzenia
Proces kodowania i obsługi dołączonego zdarzenia jest zasadniczo taki sam jak w przypadku zdarzenia nieprzyłączonego kierowanego.
Jak wspomniano wcześniej, istniejące zdarzenia dołączone do WPF zwykle nie mają być obsługiwane bezpośrednio w WPF. Częściej celem dołączonego zdarzenia jest włączenie elementu w kontrolce złożonej w celu zgłoszenia stanu do elementu nadrzędnego w kontrolce. W tym scenariuszu zdarzenie jest wywoływane w kodzie i opiera się na obsłudze klas w odpowiedniej klasie nadrzędnej. Na przykład oczekuje się, że elementy w obiekcie Selector będą zgłaszać Selected dołączone zdarzenie, które jest następnie klasą obsługiwaną przez klasę Selector . Klasa Selector potencjalnie konwertuje Selected zdarzenie na SelectionChanged zdarzenie kierowane. Aby uzyskać więcej informacji o zdarzeniach kierowanych i obsłudze klas, zobacz Oznaczanie zdarzeń trasowanych jako obsługiwanych i obsługa klas.
Definiowanie niestandardowego dołączonego zdarzenia
Jeśli pochodzisz z typowych klas bazowych WPF, możesz zaimplementować niestandardowe dołączone zdarzenie, włączając dwie metody dostępu w klasie. Te metody to:
Metoda Addevent< nameHandler> z pierwszym parametrem, który jest elementem, na którym jest dołączony program obsługi zdarzeń, a drugi parametr, który jest programem obsługi zdarzeń do dodania. Metoda musi być
publicistatic, bez wartości zwracanej. Metoda wywołuje metodę klasy bazowej AddHandler , przekazując zdarzenie kierowane i procedurę obsługi jako argumenty. Ta metoda obsługuje składnię atrybutów XAML do dołączania procedury obsługi zdarzeń do elementu. Ta metoda umożliwia również dostęp kodu do magazynu obsługi zdarzeń dla dołączonego zdarzenia.Metoda Removeevent< nameHandler> z pierwszym parametrem, który jest elementem, na którym jest dołączony program obsługi zdarzeń, a drugi parametr, który jest procedurą obsługi zdarzeń do usunięcia. Metoda musi być
publicistatic, bez wartości zwracanej. Metoda wywołuje metodę klasy bazowej RemoveHandler , przekazując zdarzenie kierowane i procedurę obsługi jako argumenty. Ta metoda umożliwia dostęp kodu do magazynu programu obsługi zdarzeń dla dołączonego zdarzenia.
WPF implementuje dołączone zdarzenia jako zdarzenia kierowane, ponieważ identyfikator elementu RoutedEvent jest definiowany przez system zdarzeń WPF. Ponadto routing zdarzenia jest naturalnym rozszerzeniem koncepcji na poziomie języka XAML dołączonego zdarzenia. Ta strategia implementacji ogranicza obsługę dołączonych zdarzeń do UIElement klas pochodnych lub ContentElement klas pochodnych, ponieważ tylko te klasy mają AddHandler implementacje.
Na przykład poniższy kod definiuje Clean dołączone zdarzenie w AquariumFilter klasie właściciela, która nie jest klasą elementu. Kod definiuje dołączone zdarzenie jako zdarzenie kierowane i implementuje wymagane metody dostępu.
public class AquariumFilter
{
// Register a custom routed event using the bubble routing strategy.
public static readonly RoutedEvent CleanEvent = EventManager.RegisterRoutedEvent(
"Clean", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
// Provide an add handler accessor method for the Clean event.
public static void AddCleanHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
{
if (dependencyObject is not UIElement uiElement)
return;
uiElement.AddHandler(CleanEvent, handler);
}
// Provide a remove handler accessor method for the Clean event.
public static void RemoveCleanHandler(DependencyObject dependencyObject, RoutedEventHandler handler)
{
if (dependencyObject is not UIElement uiElement)
return;
uiElement.RemoveHandler(CleanEvent, handler);
}
}
Public Class AquariumFilter
' Register a custom routed event using the bubble routing strategy.
Public Shared ReadOnly CleanEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
"Clean", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
' Provide an add handler accessor method for the Clean event.
Public Shared Sub AddCleanHandler(dependencyObject As DependencyObject, handler As RoutedEventHandler)
Dim uiElement As UIElement = TryCast(dependencyObject, UIElement)
If uiElement IsNot Nothing Then
uiElement.[AddHandler](CleanEvent, handler)
End If
End Sub
' Provide a remove handler accessor method for the Clean event.
Public Shared Sub RemoveCleanHandler(dependencyObject As DependencyObject, handler As RoutedEventHandler)
Dim uiElement As UIElement = TryCast(dependencyObject, UIElement)
If uiElement IsNot Nothing Then
uiElement.[RemoveHandler](CleanEvent, handler)
End If
End Sub
End Class
Metoda RegisterRoutedEvent zwracająca dołączony identyfikator zdarzenia jest tą samą metodą używaną do rejestrowania nieprzyłączonych zdarzeń trasowanych. Zarówno dołączone, jak i nieprzyłączone zdarzenia są rejestrowane w scentralizowanym magazynie wewnętrznym. Ta implementacja magazynu zdarzeń umożliwia pojęcie "zdarzenia jako interfejs" omówione w temacie Przegląd zdarzeń trasowanych.
W przeciwieństwie do zdarzenia CLR "otoka" używanego do tworzenia kopii zapasowych zdarzeń nieprzyłączanych, dołączone metody dostępu do zdarzeń można zaimplementować w klasach, które nie pochodzą z UIElement lub ContentElement. Jest to możliwe, ponieważ dołączony kod kopii zapasowej zdarzenia wywołuje UIElement.AddHandler metody i UIElement.RemoveHandler przekazane w UIElement wystąpieniu. Z kolei otoka CLR dla nieprzyłączanych zdarzeń trasowanych wywołuje te metody bezpośrednio w klasie będącej właścicielem, aby klasa musiała pochodzić z UIElementklasy .
Wywoływanie zdarzenia dołączonego do platformy WPF
Proces zgłaszania dołączonego zdarzenia jest zasadniczo taki sam jak w przypadku zdarzenia nieprzyłączonego kierowanego.
Zazwyczaj kod nie będzie musiał zgłaszać żadnych istniejących zdarzeń dołączonych do platformy WPF, ponieważ te zdarzenia są zgodne z ogólnym modelem koncepcyjnym "usługi". W tym modelu klasy usług, takie jak InputManager, są odpowiedzialne za podnoszenie zdarzeń dołączonych WPF.
Podczas definiowania niestandardowego dołączonego zdarzenia przy użyciu modelu WPF opartego na dołączonych zdarzeniach trasowanych użyj UIElement.RaiseEvent metody , aby zgłosić dołączone zdarzenie na dowolnym UIElement lub ContentElement. Podczas podnoszenia zdarzenia kierowanego, niezależnie od tego, czy jest on dołączony, czy nie, musisz wyznaczyć element w drzewie elementów jako źródło zdarzeń. To źródło jest następnie zgłaszane jako obiekt wywołujący RaiseEvent . Aby na przykład zgłosić AquariumFilter.Clean dołączone zdarzenie kierowane w usłudze aquarium1:
aquarium1.RaiseEvent(new RoutedEventArgs(AquariumFilter.CleanEvent));
aquarium1.[RaiseEvent](New RoutedEventArgs(AquariumFilter.CleanEvent))
W poprzednim przykładzie aquarium1 jest źródłem zdarzeń.