Gewusst wie: Erstellen eines benutzerdefinierten Routingereignisses (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. Dieser Artikel behandelt die Grundlagen der Erstellung eines benutzerdefinierten weitergeleiteten Ereignisses.
Voraussetzungen
Im Artikel wird davon ausgegangen, dass Sie grundlegende Kenntnisse über Routingereignisse besitzen und die Übersicht über Routingereignisse gelesen haben. Um den Beispielen in diesem Artikel zu folgen, ist es hilfreich, wenn Sie mit Extensible Application Markup Language (XAML) vertraut sind und wissen, wie Windows Presentation Foundation-Anwendungen (WPF-Anwendungen) geschrieben werden.
Weitergeleitete Ereignisschritte
Die grundlegenden Schritte zum Erstellen eines weitergeleiteten Ereignisses sind:
Registrieren Sie eine RoutedEvent mit der RegisterRoutedEvent-Methode.
Der Registrierungsaufruf gibt eine
RoutedEvent
-Instanz zurück, die als Routed-Ereignisbezeichner bezeichnet wird, der den registrierten Ereignisnamen, die Routingstrategie und andere Ereignisdetails enthält. Weisen Sie den Bezeichner einem statischen Readonly-Feld zu. Nach Konvention:- Der Bezeichner für ein weitergeleitetes Ereignis mit einer Bubbling-Strategie wird benannt
<event name>Event
. Wenn der Ereignisname z. B. der Name des Ereignisses istTap
, sollte der BezeichnerTapEvent
benannt werden. - Der Bezeichner für ein weitergeleitetes Ereignis mit einer Tunnelstrategie wird benannt
Preview<event name>Event
. Wenn der Ereignisname z. B. der Name des Ereignisses istTap
, sollte der BezeichnerPreviewTapEvent
benannt werden.
- Der Bezeichner für ein weitergeleitetes Ereignis mit einer Bubbling-Strategie wird benannt
Definieren Sie CLR-Add - und Remove-Ereigniszugriffer . Ohne CLR-Ereigniszugriffer können Sie nur Ereignishandler über direkte Aufrufe der UIElement.AddHandler- und UIElement.RemoveHandler-Methoden hinzufügen oder entfernen. Mit CLR-Ereigniszugriffern 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
+=
- und die-=
-Operatoren 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 Routed-Ereignis auszulösen. Ihre Logik kann z. B. das Ereignis basierend auf benutzereingaben und Anwendungsstatus auslösen.
Beispiel
Im folgenden Beispiel wird die CustomButton
-Klasse in einer benutzerdefinierten Steuerelementbibliothek implementiert. Die CustomButton
-Klasse, von Button abgeleitet wird.
- Registriert einen RoutedEvent-Namen
ConditionalClick
mithilfe der Methode und gibt die RegisterRoutedEventBubbling-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 führt die Elementstruktur aus, 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 sie ausgelöst hat:
- Das Absenderobjekt , 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, das das Element ist, das das Ereignis ursprünglich ausgelöst hat. In diesem Beispiel ist
Source
immerCustomButton
.
Hinweis
Ein wichtiger Unterschied zwischen einem routed-Ereignis und einem CLR-Ereignis besteht darin, dass ein weitergeleitetes Ereignis die Elementstruktur durchläuft und nach Handlern sucht, während ein CLR-Ereignis die Elementstruktur und Handler nicht durchlaufen, kann nur an das Quellobjekt angefügt werden, das das Ereignis ausgelöst hat. Daher kann ein weitergeleitetes Ereignis 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.
Siehe auch
.NET Desktop feedback