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 che sia stata letta 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 usando il metodo RegisterRoutedEvent.
La chiamata di registrazione restituisce un'istanza di
RoutedEvent
, nota come identificatore di evento instradato, 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 bubbling è denominato
<event name>Event
. Ad esempio, se il nome dell'evento èTap
, l'identificatore deve essere denominatoTapEvent
. - L'identificatore di un evento indirizzato che utilizza la 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 bubbling è denominato
Definire clr aggiungere e rimuovere funzioni di accesso agli eventi. Senza le funzioni di accesso agli eventi CLR, sarà possibile aggiungere o rimuovere gestori eventi solo tramite chiamate dirette ai metodi UIElement.AddHandler 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 classe CustomButton
in una libreria di controlli personalizzata. Classe CustomButton
, che deriva da Button:
- Registra un RoutedEvent denominato
ConditionalClick
usando il metodo RegisterRoutedEvent e specifica la strategia di propagazione durante la registrazione. - Assegna l'istanza di
RoutedEvent
restituita dalla chiamata di registrazione a un campo statico di sola lettura denominatoConditionalClickEvent
. - Definisce clr aggiungere e rimuovere funzioni di accesso agli eventi.
- Aggiunge una logica specifica per generare l'evento indirizzato personalizzato quando si fa clic sul
CustomButton
e quando viene applicata una condizione esterna. Anche se il codice di esempio genera l'evento indirizzatoConditionalClick
dall'interno del metodo virtuale sottoposto a overrideOnClick
, è 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 del CustomButton
a un StackPanele per assegnare il metodo Handler_ConditionalClick
come gestore eventi ConditionalClick
per gli elementi CustomButton
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 gestore eventi Handler_ConditionalClick
. 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 si fa clic su CustomButton
:
- L'evento indirizzato
ConditionalClick
viene generato inCustomButton
. - Viene attivato il gestore eventi
Handler_ConditionalClick
associato aCustomButton
. - L'evento indirizzato
ConditionalClick
attraversa l'albero degli elementi fino aStackPanel1
. - Viene attivato il gestore eventi
Handler_ConditionalClick
associato aStackPanel1
. - L'evento instradato
ConditionalClick
continua a salire lungo l'albero degli elementi, potenzialmente innescando altri gestori eventiConditionalClick
collegati ad altri elementi attraversati.
Il gestore eventi Handler_ConditionalClick
ottiene le informazioni seguenti sull'evento che lo ha attivato:
- L'oggetto mittente , che è l'elemento a cui è associato il gestore eventi. Il valore di
sender
saràCustomButton
la prima volta che il gestore viene eseguito, eStackPanel1
la seconda volta. - Oggetto RoutedEventArgs.Source, ovvero l'elemento che ha originariamente generato l'evento. In questo esempio il
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 indirizzato sender
può essere qualsiasi elemento attraversato nell'albero degli elementi.
È possibile creare un evento di tunneling allo stesso modo di un evento di bubbling, tranne che imposterai la strategia di routing nella chiamata di registrazione degli eventi su Tunnel. Per ulteriori informazioni sugli eventi di tunneling, consultare gli eventi di input di WPF .
Vedere anche
- Panoramica degli eventi instradati
- Panoramica dell'immissione
- panoramica sull'autorizzazione dei controlli
- Gestire un evento indirizzato.
.NET Desktop feedback