So erstellen Sie ein benutzerdefiniertes Routingereignis (WPF .NET)
Windows Presentation Foundation (WPF)-Anwendungsentwickler und Komponentenautoren können benutzerdefinierte weitergeleitete Ereignisse erstellen, um die Funktionalität der Ereignisse für allgemeine Sprachlaufzeit (CLR) zu erweitern. Informationen zu Routingereignisfunktionen finden Sie unter Warum routingfähige Ereignisse verwenden. In diesem Artikel werden die Grundlagen des Erstellens eines benutzerdefinierten Routingereignisses behandelt.
Voraussetzungen
Im Artikel wird davon ausgegangen, dass Sie grundlegende Kenntnisse über Routingereignisse haben und die Übersicht über Routingereignisse gelesen haben. Um den Beispielen in diesem Artikel zu folgen, hilft es Ihnen, wenn Sie mit Extensible Application Markup Language (XAML) vertraut sind und wissen, wie Sie Windows Presentation Foundation (WPF)-Anwendungen schreiben.
Routingereignisschritte
Die grundlegenden Schritte zum Erstellen eines weitergeleiteten Ereignisses sind:
Registrieren Sie ein RoutedEvent mit der RegisterRoutedEvent-Methode.
Der Registrierungsaufruf gibt eine
RoutedEvent
Instanz zurück, die als Routingereignisbezeichner bezeichnet wird, der den Namen des registrierten Ereignisses, Routingstrategieund andere Ereignisdetails enthält. Weisen Sie den Bezeichner einem statischen schreibgeschützen Feld zu. Nach Konvention:- Der Bezeichner für ein Routingereignis mit einer Bubbling-Strategie wird
<event name>Event
benannt. Wenn der Ereignisname beispielsweiseTap
ist, sollte der BezeichnerTapEvent
benannt werden. - Der Bezeichner für ein Routingereignis mit einer Tunnel-Strategie wird
Preview<event name>Event
benannt. Wenn der Ereignisname beispielsweiseTap
ist, sollte der BezeichnerPreviewTapEvent
benannt werden.
- Der Bezeichner für ein Routingereignis mit einer Bubbling-Strategie wird
Definieren Sie Hinzufügen von CLR und Entfernen von Ereignisaccessors. Ohne CLR-Ereigniszugriffer können Sie nur Ereignishandler über direkte Aufrufe der UIElement.AddHandler- und UIElement.RemoveHandler-Methoden hinzufügen oder entfernen. Mit CLR-Ereignisaccessors erhalten Sie diese Ereignishandlerzuweisungsmechanismen:
- Für Extensible Application Markup Language (XAML) können Sie Attributsyntax verwenden, um Ereignishandler hinzuzufügen.
- Für C# können Sie die Operatoren
+=
und-=
verwenden, um Ereignishandler hinzuzufügen oder zu entfernen. - Für VB können Sie die AddHandler- und RemoveHandler--Anweisungen verwenden, um Ereignishandler hinzuzufügen oder zu entfernen.
Fügen Sie benutzerdefinierte Logik hinzu, um das Routingereignis auszulösen. Ihre Logik kann z. B. das Ereignis basierend auf Benutzereingabe und Anwendungszustand auslösen.
Beispiel
Im folgenden Beispiel wird die CustomButton
Klasse in einer benutzerdefinierten Steuerelementbibliothek implementiert. Die CustomButton
Klasse, die von Buttonabgeleitet wird:
- Registriert einen RoutedEvent-Namen
ConditionalClick
mithilfe der Methode RegisterRoutedEvent und gibt die Bubbling-Strategie während der Registrierung an - Weist die Instanz, die
RoutedEvent
vom Registrierungsaufruf zurückgegeben wurde, einem statischen Readonly-Feld namensConditionalClickEvent
zu. - Definieren Sie CLR-Add - und Remove-Ereigniszugriffer .
- Fügt benutzerdefinierte Logik hinzu, um das benutzerdefinierte routed-Ereignis zu auslösen, wenn die
CustomButton
-Option geklickt wird und eine externe Bedingung angewendet wird. Obwohl der Beispielcode dasConditionalClick
weitergeleitete Ereignis aus der überschriebenenOnClick
virtuellen Methode auslöst, können Sie Ihr Ereignis auf jede Weise auslösen, die Sie auswählen.
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
Das Beispiel enthält eine separate WPF-Anwendung, die XAML-Markup verwendet, um eine Instanz des CustomButton
Elements StackPanelhinzuzufügen und die Handler_ConditionalClick
Methode als ConditionalClick
Ereignishandler für die CustomButton
elemente StackPanel1
zuzuweisen.
<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>
In Codebehind definiert die WPF-Anwendung die Handler_ConditionalClick
Ereignishandlermethode. Ereignishandlermethoden können nur in Codebehind implementiert werden.
// 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.
Wenn CustomButton
geklickt wurde:
- Das Routingereignis
ConditionalClick
wird aufCustomButton
ausgelöst. - Der
Handler_ConditionalClick
-Ereignishandler, der anCustomButton
angehängt wurde, wird ausgelöst. - Das
ConditionalClick
-Routingereignis durchläuft die Elementstruktur aufStackPanel1
. - Der
Handler_ConditionalClick
-Ereignishandler, der anStackPanel1
angehängt wurde, wird ausgelöst. - Das
ConditionalClick
-Routingereignis folgt der Elementstruktur, die möglicherweise andereConditionalClick
-Ereignishandler auslösen, die an andere durchlaufene Elemente angefügt sind.
Der Handler_ConditionalClick
-Ereignishandler ruft die folgenden Informationen zum Ereignis ab, das es ausgelöst hat:
- Das Sender-Objekt, das das Element ist, an das der Ereignishandler angefügt ist
sender
istCustomButton
, wenn der Handler das erste Mal ausgeführt wird, undStackPanel1
das zweite Mal. - Das RoutedEventArgs.Source-Objekt, bei dem es sich um das Element handelt, das das Ereignis ursprünglich ausgelöst hat. In diesem Beispiel ist
Source
immerCustomButton
.
Anmerkung
Ein wichtiger Unterschied zwischen einem routbaren Ereignis und einem CLR-Ereignis besteht darin, dass ein routbares Ereignis die Elementstruktur durchläuft und nach Handlern sucht, während ein CLR-Ereignis dies nicht tut und Handler nur an das Quellobjekt angefügt werden können, das das Ereignis ausgelöst hat. Daher kann ein Routingereignis sender
jedes durchlaufene Element in der Elementstruktur sein.
Sie können ein Tunneling-Ereignis auf dieselbe Weise wie ein Bubbling-Ereignis erstellen, außer sie legen die Routingstrategie im Ereignisregistrierungsaufruf fest Tunnel. Weitere Informationen zu Tunnelereignissen finden Sie unter WPF-Eingabeereignisse.
Weitere Informationen
.NET Desktop feedback