Jak utworzyć niestandardowe zdarzenie kierowane (WPF .NET)
Deweloperzy aplikacji i autorzy składników programu Windows Presentation Foundation (WPF) mogą tworzyć niestandardowe zdarzenia kierowane w celu rozszerzenia funkcjonalności zdarzeń środowiska uruchomieniowego języka wspólnego (CLR). Aby uzyskać informacje na temat możliwości zdarzenia kierowanego, zobacz Dlaczego warto używać zdarzeń trasowanych. W tym artykule opisano podstawy tworzenia niestandardowego zdarzenia kierowanego.
Wymagania wstępne
W tym artykule przyjęto założenie, że masz podstawową wiedzę na temat zdarzeń kierowanych i zapoznasz się z omówieniem 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 przy RoutedEvent użyciu RegisterRoutedEvent metody .
Wywołanie rejestracji zwraca wystąpienie znane jako identyfikator zdarzenia kierowanego, który zawiera zarejestrowaną
RoutedEvent
nazwę zdarzenia, strategię routingu i inne szczegóły zdarzenia. Przypisz identyfikator do statycznego pola tylko do odczytu. Zgodnie z konwencją:- Identyfikator zdarzenia kierowanego ze strategią bubbling nosi nazwę
<event name>Event
. Jeśli na przykład nazwa zdarzenia toTap
identyfikator powinien mieć nazwęTapEvent
. - Identyfikator zdarzenia kierowanego 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ą bubbling nosi nazwę
Zdefiniuj metody dostępu do zdarzeń clR i usuń je. Bez akcesorów zdarzeń CLR będzie można dodawać lub usuwać programy obsługi zdarzeń tylko za pomocą wywołań bezpośrednich do UIElement.AddHandler metod i UIElement.RemoveHandler . Dzięki akcesorom zdarzeń CLR uzyskasz 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-=
do dodawania lub usuwania procedur obsługi zdarzeń. - W przypadku języka VB można użyć instrukcji AddHandler i RemoveHandler , aby dodać lub usunąć programy obsługi zdarzeń.
Dodaj logikę niestandardową 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 klasy Button:
- Rejestruje RoutedEvent nazwę przy
ConditionalClick
użyciu RegisterRoutedEvent metody i określa strategię bubbling podczas rejestracji. - Przypisuje wystąpienie zwrócone
RoutedEvent
z wywołania rejestracji do statycznego pola readonly o nazwieConditionalClickEvent
. - Definiuje rozszerzenie CLR add and remove event accessors (Dodawanie i usuwanie akcesorów zdarzeń).
- Dodaje logikę niestandardową w celu podniesienia niestandardowego zdarzenia kierowanego po kliknięciu
CustomButton
elementu , a warunek zewnętrzny ma zastosowanie. Mimo że przykładowy kod zgłaszaConditionalClick
zdarzenie kierowane z metody wirtualnej przesłoniętejOnClick
, 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 elementu do StackPanelklasy , oraz przypisania Handler_ConditionalClick
metody jako ConditionalClick
procedury obsługi zdarzeń dla CustomButton
elementów iStackPanel1
.CustomButton
<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 kodzie aplikacja WPF definiuje metodę Handler_ConditionalClick
obsługi zdarzeń. Metody obsługi zdarzeń można zaimplementować tylko w kodzie.
// 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 CustomButton
kliknięciu:
- Zdarzenie
ConditionalClick
kierowane jest wywoływane w plikuCustomButton
. - Wyzwalana
Handler_ConditionalClick
jest procedura obsługi zdarzeń dołączona doCustomButton
. - Zdarzenie
ConditionalClick
kierowane przechodzi w górę drzewa elementów doStackPanel1
. - Wyzwalana
Handler_ConditionalClick
jest procedura obsługi zdarzeń dołączona doStackPanel1
. - Zdarzenie
ConditionalClick
kierowane kontynuuje drzewo elementów potencjalnie wyzwalające inneConditionalClick
programy obsługi zdarzeń dołączone do innych elementów przechodzących.
Procedura Handler_ConditionalClick
obsługi zdarzeń uzyskuje następujące informacje o zdarzeniu, które go wyzwoliło:
- Obiekt nadawcy , czyli element, do którego jest dołączony program obsługi zdarzeń. Będzie
sender
toCustomButton
pierwszy raz, gdy program obsługi zostanie uruchomiony, aStackPanel1
drugi raz. - RoutedEventArgs.Source Obiekt, który jest elementem, który pierwotnie wzbudził zdarzenie. W tym przykładzie parametr ma
Source
zawszeCustomButton
wartość .
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 może być dowolnym elementem przechodzenia w drzewie elementów.
Zdarzenie tunelowania można utworzyć w taki sam sposób jak zdarzenie bubbling, z wyjątkiem ustawiania strategii routingu w wywołaniu rejestracji zdarzeń na Tunnelwartość . Aby uzyskać więcej informacji na temat zdarzeń tunelowania, zobacz Zdarzenia wejściowe WPF.
Zobacz też
.NET Desktop feedback