Przegląd dołączonych zdarzeń (WPF .NET)
Extensible Application Markup Language (XAML) definiuje składnik języka i typ zdarzenia o nazwie załączone zdarzenie. Dołączone zdarzenia mogą służyć do definiowania nowego kierowanego zdarzenia w klasie, która nie jest elementem, i wywoływania tego zdarzenia na dowolnym elemencie w drzewie. Aby to zrobić, należy zarejestrować zdarzenie dołączone jako zdarzenie kierowane i podać określony kod podstawowy, który obsługuje funkcjonalność zdarzeń dołączonych. Ponieważ dołączone zdarzenia są rejestrowane jako zdarzenia kierowane, gdy są wywoływane na elemencie, przemieszczają się przez drzewo elementów.
Warunki wstępne
W tym artykule przyjęto założenie, że podstawowa wiedza na temat zdarzeń kierowanych w programie Windows Presentation Foundation (WPF) zawiera informacje o zdarzeniach Routed i XAML wWPF. 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 zdarzenia
W składni XAML dołączone zdarzenie jest określane przez jego nazwę zdarzenia i jego typ właściciela, w postaci <owner type>.<event name>
. Ponieważ nazwa zdarzenia jest określana za pomocą nazwy typu właściciela, składnia umożliwia dołączanie zdarzenia do dowolnego elementu, który można zainicjować. Ta składnia ma również zastosowanie dla obsług regularnych zdarzeń związanych z dowolnym elementem wzdłuż ścieżki zdarzeń.
Następująca składnia atrybutu XAML dołącza procedurę obsługi AquariumFilter_Clean
dla dołączonego zdarzenia AquariumFilter.Clean
do elementu aquarium1
.
<aqua:Aquarium x:Name="aquarium1" Height="300" Width="400" aqua:AquariumFilter.Clean="AquariumFilter_Clean"/>
W tym przykładzie prefiks aqua:
jest niezbędny, ponieważ klasy AquariumFilter
i Aquarium
istnieją w innej przestrzeni nazw i zestawie środowiska uruchomieniowego języka wspólnego (CLR).
Możesz również dołączyć programy obsługi dla dołączonych zdarzeń w kodzie. W tym celu wywołaj metodę AddHandler na obiekcie, do którego program obsługi powinien się przyłączyć, a następnie przekaż identyfikator zdarzenia i program obsługi jako parametry tej metody.
Jak WPF implementuje dołączone zdarzenia
Zdarzenia dołączone do platformy WPF są implementowane jako zdarzenia kierowane wspierane przez pole RoutedEvent. W rezultacie dołączone zdarzenia przemieszczają się przez drzewo elementów po ich wywołaniu. 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 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 korzysta z dołączonych zdarzeń włączonych przez statyczne klasy Mouse lub Validation. 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. Ta ostatnia opcja jest częścią sposobu, w jaki klasa może zintegrować możliwości usługi.
System wejściowy WPF obszernie używa zdarzeń dołączanych. Jednak prawie wszystkie dołączone zdarzenia są udostępniane jako równoważne nieprzyłączone zdarzenia kierowane przez elementy bazowe. Każde kierowane zdarzenie wejściowe jest członkiem klasy podstawowego elementu i jest obsługiwane za pomocą zdarzenia CLR "opakowanie". Rzadko będziesz używać dołączonych zdarzeń lub obsługiwać je bezpośrednio. Na przykład łatwiej jest obsługiwać podstawowe dołączone zdarzenie Mouse.MouseDown na UIElement za pośrednictwem równoważnego kierowanego zdarzenia UIElement.MouseDown niż przy użyciu składni dołączonych zdarzeń w języku XAML lub za pomocą kodu.
Dołączone zdarzenia służą celowi architektury, umożliwiając przyszłe rozszerzanie urządzeń wejściowych. Na przykład nowe urządzenie wejściowe wymagałoby jedynie podniesienia Mouse.MouseDown
w celu symulowania danych wejściowych myszy i nie będzie musiało pochodzić z Mouse
, aby to zrobić. Ten scenariusz obejmuje obsługę zdarzenia przy pomocy kodu, ponieważ obsługa dołączonego zdarzenia w XAML-u nie byłaby odpowiednia.
Obsługa dołączonego zdarzenia
Proces kodowania i obsługi dołączonego zdarzenia jest zasadniczo taki sam jak dla nieprzyłączonego zdarzenia kierowanego.
Jak wspomniano wcześniej, istniejące zdarzenia dołączone do platformy WPF zwykle nie mają być obsługiwane bezpośrednio w WPF. Częściej celem dołączonego zdarzenia jest umożliwienie elementowi wewnątrz kontrolki złożonej zgłaszanie jego stanu do elementu nadrzędnego w tej 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 Selector wywołają dołączone zdarzenie Selected, które jest następnie obsługiwane przez klasę Selector
. Klasa Selector
potencjalnie konwertuje zdarzenie Selected
na zdarzenie trasowane SelectionChanged. Aby uzyskać więcej informacji na temat kierowanych zdarzeń i obsługi klas, odnieś się do Oznaczanie kierowanych zdarzeń jako obsługiwane i obsługa klas.
Definiowanie niestandardowego zdarzenia dołączonego
Jeśli dziedziczysz po typowych klasach bazowych WPF, możesz zaimplementować niestandardowe zdarzenie dołączane, poprzez dołączenie dwóch metod dostępu do klasy. Te metody to:
Metoda Add<event name>Handler, z pierwszym parametrem będącym elementem, do którego dołączony jest program obsługi zdarzeń, oraz drugim parametrem będącym programem obsługi zdarzeń, który ma zostać dodany. Metoda musi być
public
istatic
, bez zwracania wartości. Metoda wywołuje metodę AddHandler klasy bazowej, przekazując zdarzenie trasowane i procedurę obsługi jako argumenty. Ta metoda obsługuje składnię atrybutów XAML na potrzeby 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 Remove<event name>Handler, z pierwszym parametrem będącym elementem, do którego jest dołączony program obsługi zdarzeń, oraz drugim parametrem będącym programem obsługi zdarzeń do usunięcia. Metoda musi być
public
istatic
, bez wartości zwracanej. Metoda wywołuje metodę klasy bazowej RemoveHandler, przekazując jako argumenty trasowane zdarzenie oraz jego obsługę. Ta metoda umożliwia dostęp kodu do magazynu obsługi zdarzeń dla dołączonego zdarzenia.
WPF implementuje dołączone zdarzenia jako zdarzenia kierowane, ponieważ identyfikator RoutedEvent jest definiowany przez system zdarzeń WPF. Ponadto routing zdarzenia jest naturalnym rozszerzeniem koncepcji dołączonego zdarzenia na poziomie języka XAML. Ta strategia implementacji ogranicza obsługę zdarzeń dołączonych wyłącznie do klas pochodnych UIElement lub ContentElement, ponieważ tylko te klasy mają implementacje AddHandler.
Na przykład poniższy kod definiuje zdarzenie dołączone Clean
w klasie właściciela AquariumFilter
, która nie jest klasą elementów. Kod definiuje dołączone zdarzenie jako zdarzenie kierowane i implementuje wymagane metody dostępowe.
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", które zostało omówione w Przegląd zdarzeń trasowanych.
W przeciwieństwie do opakowania zdarzeń CLR używanego do obsługi zdarzeń trasowanych nieprzyłączonych, dodane metody dostępu do zdarzeń można zaimplementować w klasach, które nie dziedziczą z UIElement ani ContentElement. Jest to możliwe, ponieważ dołączony kod zapasowy zdarzenia wywołuje metody UIElement.AddHandler i UIElement.RemoveHandler na przekazanym wystąpieniu UIElement
. W przeciwieństwie do tego, osłona CLR dla nieprzyłączonych zdarzeń trasowanych wywołuje te metody bezpośrednio w klasie będącej właścicielem, więc ta klasa musi pochodzić z UIElement
.
Wywoływanie zdarzenia dołączonego do platformy WPF
Proces zgłaszania dołączonego zdarzenia jest zasadniczo taki sam jak w przypadku niedołączonego zdarzenia trasowanego.
Zazwyczaj kod nie będzie musiał zgłaszać żadnych istniejących zdarzeń dołączonych zdefiniowanych w 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 wywoływanie zdarzeń dołączonych zdefiniowanych przez platformę WPF.
Podczas definiowania niestandardowego dołączonego zdarzenia przy użyciu modelu WPF opartego na dołączonych zdarzeniach na kierowanych zdarzeńużyj metody UIElement.RaiseEvent, aby zgłosić dołączone zdarzenie na dowolnym UIElement lub ContentElement. Podczas wywoływania zdarzenia kierowanego, niezależnie od tego, czy jest ono dołączone, czy nie, musisz wyznaczyć element w drzewie elementów jako źródło zdarzenia. To źródło jest następnie zgłaszane jako obiekt wywołujący RaiseEvent
. Aby na przykład zgłosić dołączone zdarzenie AquariumFilter.Clean
kierowane na aquarium1
:
aquarium1.RaiseEvent(new RoutedEventArgs(AquariumFilter.CleanEvent));
aquarium1.[RaiseEvent](New RoutedEventArgs(AquariumFilter.CleanEvent))
W poprzednim przykładzie aquarium1
jest źródłem zdarzeń.
Zobacz też
.NET Desktop feedback