Comment créer un événement routé personnalisé (WPF .NET)
Les développeurs d’applications windows Presentation Foundation (WPF) et les auteurs de composants peuvent créer des événements routés personnalisés pour étendre les fonctionnalités des événements CLR (Common Language Runtime). Pour plus d’informations sur les fonctionnalités des événements routés, consultez Pourquoi utiliser des événements routés. Cet article décrit les principes fondamentaux de la création d’un événement routé personnalisé.
Prérequis
L’article suppose une connaissance de base des événements routés et que vous avez lu la vue d’ensemble des événements routés. Pour suivre les exemples de cet article, il vous aide à connaître le langage XAML (Extensible Application Markup Language) et savoir comment écrire des applications Windows Presentation Foundation (WPF).
Étapes des événements routés
Les étapes de base pour créer un événement routé sont les suivantes :
Inscrivez une RoutedEvent méthode à l’aide de la RegisterRoutedEvent méthode.
L’appel d’inscription retourne une
RoutedEvent
instance, appelée identificateur d’événement routé, qui contient le nom de l’événement inscrit, la stratégie de routage et d’autres détails d’événement. Affectez l’identificateur à un champ en lecture seule statique. Par convention :- L’identificateur d’un événement routé avec une stratégie de boublage est nommé
<event name>Event
. Par exemple, si le nom de l’événement estTap
alors l’identificateur doit être nomméTapEvent
. - L’identificateur d’un événement routé avec une stratégie de tunneling est nommé
Preview<event name>Event
. Par exemple, si le nom de l’événement estTap
alors l’identificateur doit être nomméPreviewTapEvent
.
- L’identificateur d’un événement routé avec une stratégie de boublage est nommé
Définissez les accesseurs d’événements d’ajout et de suppression du CLR. Sans accesseurs d’événements CLR, vous ne pourrez ajouter ou supprimer des gestionnaires d’événements que par le biais d’appels directs aux méthodes et UIElement.RemoveHandler aux UIElement.AddHandler méthodes. Avec les accesseurs d’événements CLR, vous obtenez ces mécanismes d’affectation de gestionnaire d’événements :
- Pour le langage XAML (Extensible Application Markup Language), vous pouvez utiliser la syntaxe d’attribut pour ajouter des gestionnaires d’événements.
- Pour C#, vous pouvez utiliser les
+=
opérateurs et-=
les opérateurs pour ajouter ou supprimer des gestionnaires d’événements. - Pour VB, vous pouvez utiliser les instructions AddHandler et RemoveHandler pour ajouter ou supprimer des gestionnaires d’événements.
Ajoutez une logique personnalisée pour déclencher votre événement routé. Par exemple, votre logique peut déclencher l’événement en fonction de l’état de l’entrée utilisateur et de l’application.
Exemple
L’exemple suivant implémente la CustomButton
classe dans une bibliothèque de contrôles personnalisée. La CustomButton
classe, qui dérive de Button:
- Inscrit un RoutedEvent nom
ConditionalClick
à l’aide de la RegisterRoutedEvent méthode et spécifie la stratégie de bouclage pendant l’inscription. - Affecte l’instance
RoutedEvent
retournée à partir de l’appel d’inscription à un champ en lecture seule statique nomméConditionalClickEvent
. - Définit les accesseurs d’événements d’ajout et de suppression du CLR.
- Ajoute une logique personnalisée pour déclencher l’événement routé personnalisé lorsque l’utilisateur
CustomButton
clique et qu’une condition externe s’applique. Bien que l’exemple de code déclenche l’événementConditionalClick
routé à partir de la méthode virtuelle substituéeOnClick
, vous pouvez déclencher votre événement comme vous le souhaitez.
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
L’exemple inclut une application WPF distincte qui utilise le balisage XAML pour ajouter une instance de l’instance CustomButton
à un StackPanel, et affecter la Handler_ConditionalClick
méthode en tant que ConditionalClick
gestionnaire d’événements pour les éléments et StackPanel1
les CustomButton
éléments.
<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>
Dans code-behind, l’application WPF définit la méthode du Handler_ConditionalClick
gestionnaire d’événements. Les méthodes de gestionnaire d’événements ne peuvent être implémentées que dans 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.
Quand CustomButton
un clic est fait :
- L’événement
ConditionalClick
routé est déclenché leCustomButton
. - Le
Handler_ConditionalClick
gestionnaire d’événements auquel il est attachéCustomButton
est déclenché. - L’événement
ConditionalClick
routé traverse l’arborescence d’éléments versStackPanel1
. - Le
Handler_ConditionalClick
gestionnaire d’événements auquel il est attachéStackPanel1
est déclenché. - L’événement
ConditionalClick
routé poursuit l’arborescence d’éléments pouvant déclencher d’autres gestionnaires d’événementsConditionalClick
attachés à d’autres éléments parcourus.
Le Handler_ConditionalClick
gestionnaire d’événements obtient les informations suivantes sur l’événement qui l’a déclenché :
- Objet expéditeur , qui est l’élément auquel le gestionnaire d’événements est attaché.
CustomButton
Lasender
première fois que le gestionnaire s’exécute etStackPanel1
la deuxième fois. - Objet RoutedEventArgs.Source , qui est l’élément qui a déclenché l’événement à l’origine. Dans cet exemple, la valeur
Source
est toujoursCustomButton
.
Remarque
Une différence clé entre un événement routé et un événement CLR est qu’un événement routé traverse l’arborescence d’éléments, recherchant des gestionnaires, tandis qu’un événement CLR ne traverse pas l’arborescence d’éléments et les gestionnaires ne peuvent joindre qu’à l’objet source qui a déclenché l’événement. Par conséquent, un événement sender
routé peut être n’importe quel élément parcouru dans l’arborescence d’éléments.
Vous pouvez créer un événement de tunneling de la même façon qu’un événement de bubbling, sauf que vous allez définir la stratégie de routage dans l’appel Tunneld’inscription d’événement sur . Pour plus d’informations sur les événements de tunneling, consultez les événements d’entrée WPF.
Voir aussi
.NET Desktop feedback