Jak utworzyć niestandardowe zdarzenie kierowane (WPF .NET)
Deweloperzy aplikacji i autorzy składników Windows Presentation Foundation (WPF) mogą tworzyć niestandardowe zdarzenia kierowane w celu rozszerzania funkcjonalności zdarzeń środowiska uruchomieniowego CLR. Aby uzyskać informacje na temat możliwości zdarzeń trasowanych, zobacz Dlaczego warto używać zdarzeń trasowanych. W tym artykule opisano podstawy tworzenia niestandardowego zdarzenia routingu.
Warunki wstępne
Artykuł zakłada podstawową znajomość zdarzeń trasowanych, przy czym należy zapoznać się z Przegląd zdarzeń trasowanych. Aby postępować zgodnie z przykładami w tym artykule, warto zapoznać się z językiem Extensible Application Markup Language (XAML) i wiedzieć, jak pisać aplikacje programu Windows Presentation Foundation (WPF).
Kroki zdarzenia kierowanego
Podstawowe kroki tworzenia zdarzenia kierowanego to:
Zarejestruj RoutedEvent przy użyciu metody RegisterRoutedEvent.
Wywołanie rejestracji zwraca wystąpienie
RoutedEvent
, znane jako identyfikator zdarzenia kierowanego. Przechowuje ono zarejestrowaną nazwę zdarzenia, strategię routingui inne szczegóły zdarzenia. Przypisz identyfikator do statycznego pola tylko do odczytu. Zgodnie z konwencją:- Identyfikator zdarzenia kierowanego ze strategią
nosi nazwę . Jeśli na przykład nazwa zdarzenia to Tap
identyfikator powinien mieć nazwęTapEvent
. - Identyfikator dla zdarzenia z trasowaniem ze strategią tunelowania nosi nazwę
Preview<event name>Event
. Jeśli na przykład nazwa zdarzenia toTap
identyfikator powinien mieć nazwęPreviewTapEvent
.
- Identyfikator zdarzenia kierowanego ze strategią
Zdefiniuj akcesory dostępu do zdarzeń CLR dla , dodaj i , usuń. Bez metod obsługi zdarzeń CLR można dodawać lub usuwać programy obsługi zdarzeń tylko za pomocą wywołań bezpośrednich do metod UIElement.AddHandler i UIElement.RemoveHandler. Dzięki akcesorom zdarzeń CLR możesz zastosować następujące mechanizmy przypisywania obsługi zdarzeń:
- W przypadku rozszerzalnego języka znaczników aplikacji (XAML) można użyć składni atrybutów, aby dodać programy obsługi zdarzeń.
- W języku C# można użyć operatorów
+=
i-=
, aby dodawać lub usuwać programy obsługi zdarzeń. - W przypadku języka VB można użyć instrukcji AddHandler i RemoveHandler, aby dodawać lub usuwać programy obsługi zdarzeń.
Dodaj niestandardową logikę do wyzwalania zdarzenia kierowanego. Na przykład logika może wyzwolić zdarzenie na podstawie danych wejściowych użytkownika i stanu aplikacji.
Przykład
Poniższy przykład implementuje klasę CustomButton
w niestandardowej bibliotece kontrolek. Klasa CustomButton
, która pochodzi z Button:
- Rejestruje RoutedEvent o nazwie
ConditionalClick
przy użyciu metody RegisterRoutedEvent i określa strategię podczas rejestracji. - Przypisuje wystąpienie
RoutedEvent
zwrócone z wywołania rejestracji do statycznego pola tylko do odczytu o nazwieConditionalClickEvent
. - Definiuje akcesory zdarzeń dodawania i usuwania dla CLR dodać i usunąć.
- Dodaje niestandardową logikę, aby wywołać niestandardowe zdarzenie kierowane, gdy
CustomButton
jest kliknięty i spełniony jest warunek zewnętrzny. Mimo że przykładowy kod zgłasza zdarzenie kierowaneConditionalClick
w ramach nadpisanej metody wirtualnejOnClick
, możesz zgłosić zdarzenie w dowolny sposób.
public class CustomButton : Button
{
// Register a custom routed event using the Bubble routing strategy.
public static readonly RoutedEvent ConditionalClickEvent = EventManager.RegisterRoutedEvent(
name: "ConditionalClick",
routingStrategy: RoutingStrategy.Bubble,
handlerType: typeof(RoutedEventHandler),
ownerType: typeof(CustomButton));
// Provide CLR accessors for assigning an event handler.
public event RoutedEventHandler ConditionalClick
{
add { AddHandler(ConditionalClickEvent, value); }
remove { RemoveHandler(ConditionalClickEvent, value); }
}
void RaiseCustomRoutedEvent()
{
// Create a RoutedEventArgs instance.
RoutedEventArgs routedEventArgs = new(routedEvent: ConditionalClickEvent);
// Raise the event, which will bubble up through the element tree.
RaiseEvent(routedEventArgs);
}
// For demo purposes, we use the Click event as a trigger.
protected override void OnClick()
{
// Some condition combined with the Click event will trigger the ConditionalClick event.
if (DateTime.Now > new DateTime())
RaiseCustomRoutedEvent();
// Call the base class OnClick() method so Click event subscribers are notified.
base.OnClick();
}
}
Public Class CustomButton
Inherits Button
' Register a custom routed event with the Bubble routing strategy.
Public Shared ReadOnly ConditionalClickEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
name:="ConditionalClick",
routingStrategy:=RoutingStrategy.Bubble,
handlerType:=GetType(RoutedEventHandler),
ownerType:=GetType(CustomButton))
' Provide CLR accessors to support event handler assignment.
Public Custom Event ConditionalClick As RoutedEventHandler
AddHandler(value As RoutedEventHandler)
[AddHandler](ConditionalClickEvent, value)
End AddHandler
RemoveHandler(value As RoutedEventHandler)
[RemoveHandler](ConditionalClickEvent, value)
End RemoveHandler
RaiseEvent(sender As Object, e As RoutedEventArgs)
[RaiseEvent](e)
End RaiseEvent
End Event
Private Sub RaiseCustomRoutedEvent()
' Create a RoutedEventArgs instance.
Dim routedEventArgs As New RoutedEventArgs(routedEvent:=ConditionalClickEvent)
' Raise the event, which will bubble up through the element tree.
[RaiseEvent](routedEventArgs)
End Sub
' For demo purposes, we use the Click event as a trigger.
Protected Overrides Sub OnClick()
' Some condition combined with the Click event will trigger the ConditionalClick event.
If Date.Now > New DateTime() Then RaiseCustomRoutedEvent()
' Call the base class OnClick() method so Click event subscribers are notified.
MyBase.OnClick()
End Sub
End Class
Przykład zawiera oddzielną aplikację WPF, która używa znaczników XAML w celu dodania wystąpienia CustomButton
do StackPaneli przypisania metody Handler_ConditionalClick
jako procedury obsługi zdarzeń ConditionalClick
dla elementów CustomButton
i StackPanel1
.
<Window x:Class="CodeSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:WpfControl;assembly=WpfControlLibrary"
Title="How to create a custom routed event" Height="100" Width="300">
<StackPanel Name="StackPanel1" custom:CustomButton.ConditionalClick="Handler_ConditionalClick">
<custom:CustomButton
Name="customButton"
ConditionalClick="Handler_ConditionalClick"
Content="Click to trigger a custom routed event"
Background="LightGray">
</custom:CustomButton>
</StackPanel>
</Window>
W pliku code-behind aplikacja WPF definiuje metodę obsługi zdarzenia Handler_ConditionalClick
. Metody obsługi zdarzeń można zaimplementować tylko w code-behind.
// The ConditionalClick event handler.
private void Handler_ConditionalClick(object sender, RoutedEventArgs e)
{
string senderName = ((FrameworkElement)sender).Name;
string sourceName = ((FrameworkElement)e.Source).Name;
Debug.WriteLine($"Routed event handler attached to {senderName}, " +
$"triggered by the ConditionalClick routed event raised on {sourceName}.");
}
// Debug output when CustomButton is clicked:
// Routed event handler attached to CustomButton,
// triggered by the ConditionalClick routed event raised on CustomButton.
// Routed event handler attached to StackPanel1,
// triggered by the ConditionalClick routed event raised on CustomButton.
' The ConditionalClick event handler.
Private Sub Handler_ConditionalClick(sender As Object, e As RoutedEventArgs)
Dim sourceName As String = CType(e.Source, FrameworkElement).Name
Dim senderName As String = CType(sender, FrameworkElement).Name
Debug.WriteLine($"Routed event handler attached to {senderName}, " +
$"triggered by the ConditionalClick routed event raised on {sourceName}.")
End Sub
' Debug output when CustomButton is clicked:
' Routed event handler attached to CustomButton,
' triggered by the ConditionalClick routed event raised on CustomButton.
' Routed event handler attached to StackPanel1,
' triggered by the ConditionalClick routed event raised on CustomButton.
Po kliknięciu CustomButton
:
- Zdarzenie kierowane
ConditionalClick
jest wyzwalane wCustomButton
. - Program obsługi zdarzeń
Handler_ConditionalClick
dołączony doCustomButton
zostaje wyzwolony. - Zdarzenie kierowane
ConditionalClick
wędruje w górę drzewa elementów doStackPanel1
. - Zostanie wyzwolony program obsługi zdarzeń
Handler_ConditionalClick
dołączony doStackPanel1
. - Zdarzenie kierowane
ConditionalClick
przemieszcza się w górę drzewa elementów, potencjalnie wyzwalając inne procedury obsługi zdarzeńConditionalClick
dołączone do innych napotkanych elementów.
Program obsługi zdarzeń Handler_ConditionalClick
uzyskuje następujące informacje o zdarzeniu, które go wyzwoliło:
- Obiekt nadawcy
, do którego jest dołączony program obsługi zdarzeń. sender
zostanieCustomButton
przy pierwszym uruchomieniu obsługi, aStackPanel1
przy drugim. - Obiekt RoutedEventArgs.Source, będący elementem, który pierwotnie zgłosił zdarzenie. W tym przykładzie
Source
jest zawszeCustomButton
.
Uwaga
Kluczową różnicą między zdarzeniem kierowanym a zdarzeniem CLR jest to, że zdarzenie kierowane przechodzi przez drzewo elementów, szukając procedur obsługi, podczas gdy zdarzenie CLR nie przechodzi przez drzewo elementów i programy obsługi mogą dołączać tylko do obiektu źródłowego, który wywołał zdarzenie. W związku z tym zdarzenie sender
kierowane trasą może być dowolnym elementem przechodzonym w drzewie elementów.
Możesz utworzyć zdarzenie tunelowania w taki sam sposób jak zdarzenie bubbling, z wyjątkiem ustawiania strategii routingu w wywołaniu rejestracji zdarzeń na Tunnel. Aby uzyskać więcej informacji na temat zdarzeń tunelowania, zobacz zdarzenia wejściowe WPF.
Zobacz też
- przeglądu zdarzeń trasowanych
- Omówienie danych wejściowych
- Przegląd tworzenia kontrolek Control
- Obsługa zdarzenia kierowanego.
.NET Desktop feedback