Come creare un evento indirizzato personalizzato (WPF .NET)
Gli sviluppatori di applicazioni e gli autori di componenti di Windows Presentation Foundation (WPF) possono creare eventi indirizzati personalizzati per estendere la funzionalità degli eventi CLR (Common Language Runtime). Per informazioni sulle funzionalità degli eventi indirizzati, vedere Perché usare gli eventi indirizzati. Questo articolo illustra le nozioni di base per la creazione di un evento indirizzato personalizzato.
Prerequisiti
L'articolo presuppone una conoscenza di base degli eventi indirizzati e di aver letto panoramica degli eventi indirizzati. Per seguire gli esempi in questo articolo, è utile se si ha familiarità con Extensible Application Markup Language (XAML) e si sa come scrivere applicazioni Windows Presentation Foundation (WPF).
Passaggi dell'evento indirizzato
I passaggi di base per creare un evento indirizzato sono:
Registrare un RoutedEvent oggetto usando il RegisterRoutedEvent metodo .
La chiamata di registrazione restituisce un'istanza
RoutedEvent
, nota come identificatore di evento indirizzato, che contiene il nome dell'evento registrato, la strategia di routing e altri dettagli dell'evento. Assegnare l'identificatore a un campo statico di sola lettura. Per convenzione:- L'identificatore di un evento indirizzato con una strategia di bubbling è denominato
<event name>Event
. Ad esempio, se il nome dell'evento èTap
, l'identificatore deve essere denominatoTapEvent
. - L'identificatore di un evento indirizzato con una strategia di tunneling è denominato
Preview<event name>Event
. Ad esempio, se il nome dell'evento èTap
, l'identificatore deve essere denominatoPreviewTapEvent
.
- L'identificatore di un evento indirizzato con una strategia di bubbling è denominato
Definire le funzioni di accesso agli eventi di aggiunta e rimozione di CLR. Senza le funzioni di accesso agli eventi CLR, sarà possibile aggiungere o rimuovere gestori eventi solo tramite chiamate dirette ai UIElement.AddHandler metodi e UIElement.RemoveHandler . Con le funzioni di accesso agli eventi CLR, si ottengono questi meccanismi di assegnazione del gestore eventi:
- Per Extensible Application Markup Language (XAML), puoi usare la sintassi degli attributi per aggiungere gestori eventi.
- Per C#, è possibile usare gli
+=
operatori e-=
per aggiungere o rimuovere gestori eventi. - Per VB, è possibile usare le istruzioni AddHandler e RemoveHandler per aggiungere o rimuovere gestori eventi.
Aggiungere logica personalizzata per attivare l'evento indirizzato. Ad esempio, la logica potrebbe attivare l'evento in base all'input utente e allo stato dell'applicazione.
Esempio
Nell'esempio seguente viene implementata la CustomButton
classe in una libreria di controlli personalizzata. Classe CustomButton
, che deriva da Button:
- Registra un RoutedEvent oggetto denominato
ConditionalClick
usando il RegisterRoutedEvent metodo e specifica la strategia di bubbling durante la registrazione. - Assegna l'istanza
RoutedEvent
restituita dalla chiamata di registrazione a un campo di sola lettura statico denominatoConditionalClickEvent
. - Definisce le funzioni di accesso agli eventi di aggiunta e rimozione di CLR.
- Aggiunge logica personalizzata per generare l'evento indirizzato personalizzato quando
CustomButton
si fa clic su e viene applicata una condizione esterna. Anche se il codice di esempio genera l'eventoConditionalClick
indirizzato dall'interno del metodo virtuale sottopostoOnClick
a override, è possibile generare l'evento in qualsiasi modo scelto.
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'esempio include un'applicazione WPF separata che usa il markup XAML per aggiungere un'istanza CustomButton
di a un StackPaneloggetto e per assegnare il Handler_ConditionalClick
metodo come ConditionalClick
gestore eventi per gli CustomButton
elementi e 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>
Nel code-behind l'applicazione WPF definisce il metodo del Handler_ConditionalClick
gestore eventi. I metodi del gestore eventi possono essere implementati solo nel 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.
Quando CustomButton
si fa clic su:
- L'evento
ConditionalClick
indirizzato viene generato suCustomButton
. - Viene attivato il
Handler_ConditionalClick
gestore eventi associato aCustomButton
. - L'evento
ConditionalClick
indirizzato attraversa l'albero degli elementi aStackPanel1
. - Viene attivato il
Handler_ConditionalClick
gestore eventi associato aStackPanel1
. - L'evento
ConditionalClick
indirizzato continua l'albero degli elementi attivando potenzialmente altriConditionalClick
gestori eventi collegati ad altri elementi attraversati.
Il Handler_ConditionalClick
gestore eventi ottiene le informazioni seguenti sull'evento che lo ha attivato:
- Oggetto sender , ovvero l'elemento a cui è associato il gestore eventi.
sender
saràCustomButton
la prima volta che viene eseguito il gestore eStackPanel1
la seconda volta. - Oggetto RoutedEventArgs.Source , ovvero l'elemento che ha originariamente generato l'evento. In questo esempio, è
Source
sempreCustomButton
.
Nota
Una differenza fondamentale tra un evento indirizzato e un evento CLR consiste nel fatto che un evento indirizzato attraversa l'albero degli elementi, cercando gestori, mentre un evento CLR non attraversa l'albero degli elementi e i gestori possono essere collegati solo all'oggetto di origine che ha generato l'evento. Di conseguenza, un evento sender
indirizzato può essere qualsiasi elemento attraversato nell'albero degli elementi.
È possibile creare un evento di tunneling allo stesso modo di un evento di bubbling, ad eccezione della strategia di routing nella chiamata di registrazione eventi a Tunnel. Per altre informazioni sugli eventi di tunneling, vedere Eventi di input WPF.
Vedi anche
.NET Desktop feedback