Condividi tramite


Cenni preliminari sugli eventi associati

Extensible Application Markup Language (XAML) definisce un componente del linguaggio e un tipo di evento noto come evento associato. Il concetto di evento associato consente di aggiungere un gestore per un determinato evento a un elemento arbitrario, anziché a un elemento che definisce o eredita effettivamente l'evento. In questo caso, né l'oggetto che genera potenzialmente l'evento, né l'istanza di gestione di destinazione definisce o possiede in altro modo l'evento.

Nel presente argomento sono contenute le seguenti sezioni.

  • Prerequisiti
  • Sintassi dell'evento associato
  • Modalità di implementazione degli eventi associati in WPF
  • Scenari per gli eventi associati
  • Gestione di un evento associato in WPF
  • Definizione di eventi associati personalizzati come eventi indirizzati
  • Generazione di un evento associato WPF
  • Argomenti correlati

Prerequisiti

In questo argomento si presuppone la lettura di Cenni preliminari sugli eventi indirizzati e Cenni preliminari su XAML (WPF).

Sintassi dell'evento associato

Per supportare l'utilizzo degli eventi associati, è necessario che il codice sottostante utilizzi una sintassi XAML e un modello di codifica specifici di tali eventi.

Nella sintassi XAML, l'evento associato non è specificato solo dal nome di evento, ma dal tipo proprietario e dal nome di evento, separati da un punto (.). Poiché il nome di evento è qualificato con il nome del tipo proprietario, la sintassi dell'evento associato consente l'associazione di tale evento a qualsiasi elemento di cui è possibile creare un'istanza.

Ad esempio, di seguito viene illustrata la sintassi XAML per collegare un gestore per un evento associato NeedsCleaning personalizzato:

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

Si noti il prefisso aqua:, necessario in questo caso poiché l'evento associato è un evento personalizzato tratto da un xmlns mappato personalizzato.

Modalità di implementazione degli eventi associati in WPF

In WPF, gli eventi associati sono supportati da un campo RoutedEvent e sono indirizzati attraverso la struttura ad albero dopo essere stati generati. In genere, l'origine dell'evento associato (oggetto che genera l'evento) è un'origine di sistema o servizio e l'oggetto che esegue il codice che genera l'evento non è pertanto parte diretta della struttura ad albero dell'elemento.

Scenari per gli eventi associati

In WPF, gli eventi associati sono presenti in alcune aree di funzionalità in cui vi è astrazione del livello di servizio, ad esempio per gli eventi abilitati dalla classe Mouse statica o dalla classe Validation. Le classi che interagiscono con il servizio o lo utilizzano possono utilizzare l'evento nella sintassi dell'evento associato o scegliere di utilizzarlo come un evento indirizzato che fa parte del modo in cui la classe integra le funzionalità del servizio.

Anche se in WPF vengono definiti vari eventi associati, gli scenari in cui si utilizza o si gestisce direttamente l'evento associato sono molto limitati. Generalmente, l'evento associato assolve uno scopo nell'architettura, ma viene inoltrato a un evento indirizzato non associato (supportato da un wrapper di eventi CLR).

Ad esempio, l'evento associato sottostante Mouse.MouseDown può essere gestito più facilmente su qualsiasi UIElement specificato utilizzando MouseDown su tale UIElement, anziché utilizzare la sintassi dell'evento associato in XAML o nel codice. L'evento associato assolve a uno scopo nell'architettura poiché consente l'espansione futura dei dispositivi di input. Sarebbe sufficiente che il dispositivo ipotetico generasse Mouse.MouseDown per simulare l'input del mouse, senza la necessità di derivare da Mouse a tale scopo. Questo scenario comporta tuttavia la gestione di codice degli eventi e la gestione di XAML dell'evento associato non è attinente a questo scenario.

Gestione di un evento associato in WPF

Il processo di gestione di un evento associato e il codice del gestore che verrà scritto è fondamentalmente lo stesso necessario per un evento indirizzato.

In genere, un evento associato WPFnon è molto diverso da un evento indirizzato WPF. Le differenze sono date dalla modalità di origine dell'evento e della relativa esposizione da parte di una classe come membro, operazione che ha anche effetto sulla sintassi del gestore XAML.

Tuttavia, come indicato in precedenza, gli eventi associati WPF esistenti non sono destinati in modo particolare alla gestione in WPF. Più spesso, lo scopo dell'evento è quello di consentire la segnalazione di uno stato da parte di un elemento composto a un elemento padre nella composizione, nel qual caso l'evento viene in genere generato nel codice e si basa inoltre sulla gestione della classe nella classe padre rilevante. Ad esempio, è previsto che elementi all'interno di Selector generino l'evento Selected associato, che viene quindi gestito dalla classe Selector e potenzialmente convertito dalla classe Selector in un evento indirizzato diverso, SelectionChanged. Per ulteriori informazioni sugli eventi indirizzati e sulla gestione delle classi, vedere Contrassegno degli eventi indirizzati come gestiti e gestione delle classi.

Definizione di eventi associati personalizzati come eventi indirizzati

Se si deriva da classi di base WPF comuni, è possibile implementare eventi associati personalizzati mediante l'inclusione di alcuni metodi del modello nella classe e l'utilizzo di metodi dell'utilità già presenti sulle classi di base.

Il modello è il seguente:

  • Un metodo Add*Handler con due parametri. Il primo parametro deve identificare l'evento, il quale deve corrispondere ai nomi con il segno * nel nome del metodo. Il secondo parametro è il gestore da aggiungere. Il metodo deve essere pubblico e statico, senza valore restituito.

  • Un metodo Remove*Handler con due parametri. Il primo parametro deve identificare l'evento, il quale deve corrispondere ai nomi con il segno * nel nome del metodo. Il secondo parametro è il gestore da rimuovere. Il metodo deve essere pubblico e statico, senza valore restituito.

Il metodo della funzione di accesso Add*Handler facilita l'elaborazione XAML quando su un elemento vengono dichiarati attributi del gestore dell'evento associato. I metodi Add*Handler e Remove*Handler abilitano inoltre l'accesso del codice all'archivio del gestore eventi per l'evento associato.

Questo modello generale non è ancora sufficientemente preciso per l'implementazione pratica in un framework, poiché qualsiasi implementazione del lettore XAML specificata può avere schemi diversi per l'identificazione di eventi sottostanti nel linguaggio e nell'architettura di supporto. Questo è uno dei motivi per cui in WPF gli eventi associati vengono implementati come eventi indirizzati. L'identificatore da utilizzare per un evento (RoutedEvent) è già definito dal sistema di eventi WPF. Il routing di un evento, inoltre, è una naturale estensione dell'implementazione nel concetto di evento associato al livello di linguaggio XAML.

L'implementazione Add*Handler per un evento associato WPF è costituita dalla chiamata a AddHandler con l'evento indirizzato e il gestore come argomenti.

Questa strategia di implementazione e il sistema degli eventi indirizzati limitano in genere la gestione degli eventi associati alle classi derivate da UIElement o da ContentElement, poiché solo tali classi dispongono di implementazioni di AddHandler.

Ad esempio, nel codice riportato di seguito viene definito l'evento associato NeedsCleaning sulla classe del proprietario Aquarium, utilizzando la strategia WPF di dichiarazione dell'evento associato come evento indirizzato.

Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub
Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
    Dim uie As UIElement = TryCast(d, UIElement)
    If uie IsNot Nothing Then
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
    End If
End Sub
public static readonly RoutedEvent NeedsCleaningEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AquariumFilter));
public static void AddNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}
public static void RemoveNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
    UIElement uie = d as UIElement;
    if (uie != null)
    {
        uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler);
    }
}

Si noti che il metodo utilizzato per definire il campo identificatore dell'evento associato, RegisterRoutedEventè in realtà lo stesso metodo utilizzato per registrare un evento indirizzato non associato. Eventi associati ed eventi indirizzati vengono registrati in un archivio interno centralizzato. Questa implementazione dell'archivio degli eventi consente la considerazione del concetto di "eventi come interfaccia" presentata in Cenni preliminari sugli eventi indirizzati.

Generazione di un evento associato WPF

Non è in genere necessario generare dal codice eventi associati esistenti definiti in WPF. Questi eventi rispettano il modello basilare generale di "servizio" e le classi di servizio, come InputManager, sono responsabili della generazione degli eventi.

Tuttavia, nella definizione di un evento associato personalizzato basato sul modello WPF per il quale gli eventi associati sono basati su RoutedEvent, è possibile utilizzare RaiseEvent per generare un evento associato da qualsiasi UIElement o ContentElement. La generazione di un evento indirizzato (associato o meno) richiede la dichiarazione di un determinato elemento nella struttura ad albero dell'elemento come origine evento. Tale origine è riportata come chiamante di RaiseEvent. È responsabilità del servizio determinare quale elemento viene riportato come origine nella struttura ad albero.

Vedere anche

Concetti

Cenni preliminari sugli eventi indirizzati

Descrizione dettagliata della sintassi XAML

Classi XAML e personalizzate per WPF