Przegląd Załączone zdarzenia

Extensible Application Markup Language (XAML) definiuje składnik języka i typ zdarzenia nazywane dołączonym zdarzeniem. Koncepcja dołączonego zdarzenia umożliwia dodanie programu obsługi dla określonego zdarzenia do dowolnego elementu, a nie do elementu, który faktycznie definiuje lub dziedziczy zdarzenie. W takim przypadku ani obiekt potencjalnie nie zgłasza zdarzenia, ani wystąpienie obsługi docelowej nie definiuje ani w inny sposób "jest właścicielem" zdarzenia.

Wymagania wstępne

W tym temacie założono, że przeczytano omówienie zdarzeń trasowanych i XAML w WPF.

Dołączona składnia zdarzenia

Dołączone zdarzenia mają składnię XAML i wzorzec kodowania, który musi być używany przez kod pomocniczy w celu obsługi dołączonego użycia zdarzeń.

W składni XAML dołączone zdarzenie jest określane nie tylko przez jego nazwę zdarzenia, ale przez własny typ plus nazwę zdarzenia, oddzielone kropką (.). Ponieważ nazwa zdarzenia jest kwalifikowana przy użyciu nazwy typu będącego właścicielem, dołączona składnia zdarzenia umożliwia dołączanie dowolnego dołączonego zdarzenia do dowolnego elementu, który można utworzyć.

Na przykład poniżej przedstawiono składnię XAML służącą do dołączania programu obsługi dla zdarzenia dołączonego niestandardowego NeedsCleaning :

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

Zwróć uwagę na aqua: prefiks; prefiks jest niezbędny w tym przypadku, ponieważ dołączone zdarzenie jest zdarzeniem niestandardowym pochodzącym z niestandardowych mapowanych xmln.

Jak WPF implementuje dołączone zdarzenia

W WPF dołączone zdarzenia są wspierane przez RoutedEvent pole i są kierowane przez drzewo po ich wywołaniu. Zazwyczaj źródłem dołączonego zdarzenia (obiekt, który zgłasza zdarzenie) jest system lub źródło usługi, a obiekt, który uruchamia kod, który wywołuje zdarzenie, nie jest zatem bezpośrednią częścią drzewa elementów.

Scenariusze dotyczące dołączonych zdarzeń

W WPF dołączone zdarzenia są obecne w niektórych obszarach funkcji, w których istnieje abstrakcji na poziomie usługi, takich jak zdarzenia włączone przez klasę statyczną Mouse lub klasę Validation . Klasy wchodzące w interakcję z usługą lub korzystające z niej mogą używać zdarzenia w dołączonej składni zdarzenia lub mogą zdecydować się na uwidomienie dołączonego zdarzenia jako zdarzenia kierowanego, które jest częścią sposobu, w jaki klasa integruje możliwości usługi.

Chociaż WPF definiuje wiele dołączonych zdarzeń, scenariusze, w których będzie używane lub obsługiwane bezpośrednio dołączone zdarzenie, są bardzo ograniczone. Ogólnie rzecz biorąc, dołączone zdarzenie służy do celów architektury, ale jest następnie przekazywane do nieprzyłączonego (wspieranego za pomocą zdarzenia CLR "otoka") kierowanego zdarzenia.

Na przykład bazowe dołączone zdarzenie można łatwiej obsłużyć na dowolnym UIElement danym za pomocą polecenia MouseDown , UIElement zamiast radzić sobie z dołączoną składnią zdarzeń Mouse.MouseDown w języku XAML lub kodzie. Dołączone zdarzenie służy celowi w architekturze, ponieważ umożliwia przyszłe rozszerzanie urządzeń wejściowych. Hipotetyczne urządzenie musiałby podnieść Mouse.MouseDown tylko w celu symulowania danych wejściowych myszy i nie musiałby z tego korzystać Mouse . Jednak ten scenariusz obejmuje obsługę kodu zdarzeń, a obsługa kodu XAML dołączonego zdarzenia nie ma znaczenia dla tego scenariusza.

Obsługa dołączonego zdarzenia w WPF

Proces obsługi dołączonego zdarzenia i kodu procedury obsługi, który napiszesz, jest zasadniczo taki sam jak w przypadku zdarzenia kierowanego.

Ogólnie rzecz biorąc, zdarzenie dołączone w WPF nie różni się bardzo od zdarzenia kierowanego WPF. Różnice to sposób, w jaki zdarzenie jest pozyskiwane i jak jest uwidaczniane przez klasę jako składową (która ma również wpływ na składnię programu obsługi XAML).

Jednak, jak wspomniano wcześniej, istniejące zdarzenia dołączone WPF nie są szczególnie przeznaczone do obsługi w WPF. Częściej celem zdarzenia jest umożliwienie złożonemu elementowi zgłaszania stanu do elementu nadrzędnego w komponowaniu, w którym przypadku zdarzenie jest zwykle wywoływane w kodzie, a także polega na obsłudze klas w odpowiedniej klasie nadrzędnej. Na przykład oczekuje się, że elementy w obiekcie Selector będą zgłaszać dołączone Selected zdarzenie, które jest następnie klasą obsługiwaną przez Selector klasę, a następnie potencjalnie przekonwertowane przez Selector klasę na inne zdarzenie kierowane: SelectionChanged. Aby uzyskać więcej informacji na temat kierowanych zdarzeń i obsługi klas, zobacz Oznaczanie zdarzeń trasowanych jako obsługiwane i Obsługa klas.

Definiowanie własnych dołączonych zdarzeń jako zdarzeń kierowanych

Jeśli pochodzisz z typowych klas bazowych WPF, możesz zaimplementować własne dołączone zdarzenia, włączając niektóre metody wzorca w klasie i przy użyciu metod narzędzi, które są już obecne w klasach bazowych.

Wzorzec jest następujący:

  • Metoda AddEventNameHandler z dwoma parametrami. Pierwszy parametr to wystąpienie, do którego jest dodawana procedura obsługi zdarzeń. Drugi parametr to procedura obsługi zdarzeń do dodania. Metoda musi mieć public wartość i static, bez wartości zwracanej.

  • Metoda RemoveEventNameHandler z dwoma parametrami. Pierwszy parametr to wystąpienie, z którego program obsługi zdarzeń jest usuwany. Drugi parametr to procedura obsługi zdarzeń do usunięcia. Metoda musi mieć public wartość i static, bez wartości zwracanej.

Metoda dostępu AddEventNameHandler ułatwia przetwarzanie XAML, gdy dołączone atrybuty programu obsługi zdarzeń są deklarowane na elemecie. Metody programu obsługi AddEventNamei RemoveEventNameumożliwiają również dostęp kodu do magazynu obsługi zdarzeń dla dołączonego zdarzenia.

Ten ogólny wzorzec nie jest jeszcze wystarczająco precyzyjny w przypadku praktycznej implementacji w ramach struktury, ponieważ każda implementacja czytnika XAML może mieć różne schematy identyfikowania podstawowych zdarzeń w języku pomocniczym i architekturze. Jest to jeden z powodów, dla których WPF implementuje dołączone zdarzenia jako zdarzenia kierowane; identyfikator używany dla zdarzenia (RoutedEvent) jest już zdefiniowany przez system zdarzeń WPF. Ponadto routing zdarzenia jest naturalnym rozszerzeniem implementacji w koncepcji języka XAML dołączonego zdarzenia.

Implementacja programu obsługi AddEventNamedla dołączonego zdarzenia WPF składa się z wywoływania AddHandler elementu za pomocą zdarzenia kierowanego i procedury obsługi jako argumentów.

Ta strategia implementacji i kierowany system zdarzeń w ogóle ograniczają 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 NeedsCleaning dołączone zdarzenie w klasie Aquariumwłaściciela przy użyciu strategii zdarzeń dołączonych WPF deklarowania dołączonego zdarzenia jako zdarzenia kierowanego.

public static readonly RoutedEvent NeedsCleaningEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
public static void AddNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
public static void RemoveNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub
Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub

Należy pamiętać, że metoda używana do ustanowienia dołączonego pola identyfikatora zdarzenia, RegisterRoutedEvent, jest w rzeczywistości tą samą metodą, która jest używana do rejestrowania nieprzyłączonego zdarzenia trasowanego. Dołączone zdarzenia i zdarzenia kierowane są rejestrowane w scentralizowanym magazynie wewnętrznym. Ta implementacja magazynu zdarzeń umożliwia zagadnienia koncepcyjne "zdarzenia jako interfejs", które zostały omówione w przeglądzie zdarzeń trasowanych.

Podnoszenie zdarzenia dołączonego do platformy WPF

Zwykle nie trzeba zgłaszać istniejących zdarzeń dołączonych do platformy WPF z kodu. Te zdarzenia są zgodne z ogólnym modelem koncepcyjnym "usługi" i klasami usług, takimi jak InputManager są odpowiedzialne za podnoszenie zdarzeń.

Jeśli jednak definiujesz niestandardowe dołączone zdarzenie na podstawie modelu WPF opartego na dołączonych zdarzeniach w RoutedEventsystemie , możesz użyć RaiseEvent polecenia , aby zgłosić dołączone zdarzenie z dowolnego UIElement zdarzenia lub ContentElement. Podniesienie zdarzenia kierowanego (dołączonego lub nie) wymaga zadeklarowania określonego elementu w drzewie elementów jako źródła zdarzeń; to źródło jest zgłaszane jako obiekt wywołujący RaiseEvent . Określanie, który element jest zgłaszany jako źródło w drzewie, jest odpowiedzialny za usługę

Zobacz też