Vue d’ensemble des événements attachés

Le langage XAML (Extensible Application Markup Language) définit un composant de langage et un type d’événement appelé événement attaché. Le concept d’un événement attaché vous permet d’ajouter un gestionnaire pour un événement particulier à un élément arbitraire plutôt qu’à un élément qui définit réellement l’événement ou qui en hérite. Dans ce cas, ni l’objet qui déclenche potentiellement l’événement, ni l’instance de gestion de destination ne définit ou ne « détient » l’événement.

Prérequis

Cette rubrique part du principe que vous avez lu la vue d’ensemble des événements routés et XAML dans WPF.

Syntaxe d’un événement attaché

Les événements attachés ont une syntaxe XAML et un modèle de codage qui doit être utilisé par le code de stockage pour prendre en charge l’utilisation des événements attachés.

Dans la syntaxe XAML, l’événement attaché est spécifié non seulement par son nom d’événement, mais par son type propriétaire plus le nom de l’événement, séparé par un point (.). Comme le nom de l’évènement est qualifié avec le nom de son type propriétaire, la syntaxe de l’événement attaché permet à celui-ci d’être attaché à tout élément pouvant être instancié.

Par exemple, voici la syntaxe XAML permettant d’attacher un gestionnaire pour un événement attaché personnalisé NeedsCleaning :

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

Notez le préfixe aqua:. Ce préfixe est nécessaire dans le cas présent, car l’événement attaché est un événement personnalisé qui provient d’un fichier xmlns mappé personnalisé.

Comment WPF implémente des événements attachés

Dans WPF, les événements joints sont soutenus par un RoutedEvent champ et sont routés via l’arborescence une fois qu’ils sont déclenchés. En général, la source de l’événement attaché (l’objet qui déclenche l’événement) est une source système ou de service. L’objet qui exécute le code qui déclenche l’événement ne fait donc pas directement partie de l’arborescence d’éléments.

Scénarios pour les événements attachés

Dans WPF, les événements attachés sont présents dans certaines zones de fonctionnalités où il existe une abstraction au niveau du service, par exemple pour les événements activés par la classe statique Mouse ou la Validation classe. Les classes qui interagissent avec le service, ou qui l’utilisent, peuvent employer l’événement dans la syntaxe de l’événement attaché ou choisir de surfacer l’événement attaché en tant qu’événement routé faisant partie de la façon dont la classe intègre les fonctionnalités du service.

Bien que WPF définit un certain nombre d’événements attachés, les scénarios dans lesquels vous allez utiliser ou gérer directement l’événement attaché sont très limités. En règle générale, l’événement attaché sert à un objectif d’architecture, mais il est ensuite transféré à un événement routé non attaché (soutenu par un événement CLR « wrapper »).

Par exemple, l’événement Mouse.MouseDown attaché sous-jacent peut être plus facilement géré sur n’importe quel élément donné UIElementMouseDownUIElement au lieu de traiter la syntaxe d’événement attachée en XAML ou en code. L’événement attaché a une fonction d’architecture, car il permet l’extension future des périphériques d’entrée. L’appareil hypothétique n’aurait besoin d’augmenter Mouse.MouseDown que pour simuler l’entrée de la souris, et n’aurait pas besoin de dériver pour Mouse le faire. Toutefois, ce scénario implique la gestion du code des événements et la gestion XAML de l’événement attaché n’est pas pertinente pour ce scénario.

Gestion d’un événement attaché dans WPF

La gestion d’un événement attaché et le code du gestionnaire que vous allez écrire sont essentiellement les mêmes que pour un événement routé.

En général, un événement attaché WPF n’est pas très différent d’un événement routé WPF. Les différences sont la source de l’événement et la façon dont il est exposé par une classe en tant que membre (qui affecte également la syntaxe du gestionnaire XAML).

Toutefois, comme indiqué précédemment, les événements joints WPF existants ne sont pas particulièrement destinés à la gestion dans WPF. Le plus souvent, le but de l’événement est de permettre à un élément composé de signaler un état à un élément parent au moment de la composition. Dans ce cas, l’événement est généralement déclenché dans du code et compte également sur une gestion de classe dans la classe parente appropriée. Par exemple, les éléments d’un élément Selector sont censés déclencher l’événement attachéSelected, qui est ensuite géré par la Selector classe, puis potentiellement converti par la Selector classe en un autre événement routé. SelectionChanged Pour plus d’informations sur les événements routés et la gestion de classe, consultez Marquage des événements routés comme gérés et gestion de classe.

Définition de vos propres événements attachés en tant qu’événements routés

Si vous dérivez de classes de base WPF courantes, vous pouvez implémenter vos propres événements attachés en incluant certaines méthodes de modèle dans votre classe et en utilisant des méthodes utilitaires déjà présentes sur les classes de base.

Le modèle est le suivant :

  • Méthode AddEventNameHandler avec deux paramètres. Le premier paramètre est l’instance à laquelle le gestionnaire d’événements est ajouté. Le deuxième paramètre est le gestionnaire d’événements à ajouter. La méthode doit être public et static, sans valeur de retour.

  • Méthode RemoveEventNameHandler avec deux paramètres. Le premier paramètre est l’instance à partir de laquelle le gestionnaire d’événements est supprimé. Le deuxième paramètre est le gestionnaire d’événements à supprimer. La méthode doit être public et static, sans valeur de retour.

La méthode d’accesseur AddEventNameHandler facilite le traitement XAML lorsque les attributs de gestionnaire d’événements attachés sont déclarés sur un élément. Les méthodes AddEventName Handler et RemoveEventName Handler permettent également d’accéder au code au magasin de gestionnaires d’événements pour l’événement attaché.

Ce modèle général n’est pas encore suffisamment précis pour l’implémentation pratique dans un framework, car toute implémentation de lecteur XAML donnée peut avoir des schémas différents pour identifier les événements sous-jacents dans le langage et l’architecture de prise en charge. C’est l’une des raisons pour lesquelles WPF implémente des événements attachés en tant qu’événements routés ; l’identificateur à utiliser pour un événement (RoutedEvent) est déjà défini par le système d’événements WPF. En outre, le routage d’un événement est une extension d’implémentation naturelle sur le concept de langage XAML d’un événement attaché.

L’implémentation de gestionnaire AddEventNamepour un événement attaché WPF consiste à appeler l’événement AddHandler routé et le gestionnaire en tant qu’arguments.

Cette stratégie d’implémentation et le système d’événements routés en général limitent la gestion des événements attachés aux UIElement classes dérivées ou ContentElement aux classes dérivées, car seules ces classes ont AddHandler des implémentations.

Par exemple, le code suivant définit l’événement NeedsCleaning attaché sur la classe Aquariumpropriétaire, à l’aide de la stratégie d’événement attaché WPF de la déclaration de l’événement attaché en tant qu’événement routé.

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);
    }
}
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

Notez que la méthode utilisée pour établir le champ d’identificateur d’événement attaché est RegisterRoutedEventen fait la même méthode que celle utilisée pour inscrire un événement routé non attaché. Les événements attachés et les événements routés sont tous inscrits dans un magasin interne centralisé. Cette implémentation du magasin d’événements rend possible la considération conceptuelle des « événements en tant qu’interface » traitée dans Vue d’ensemble des événements routés.

Déclenchement d’un événement attaché WPF

En règle générale, vous n’avez pas besoin de déclencher des événements joints définis par WPF existants à partir de votre code. Ces événements suivent le modèle conceptuel général « service » et les classes de service telles que InputManager celles-ci sont responsables de la déclenchement des événements.

Toutefois, si vous définissez un événement attaché personnalisé basé sur le modèle WPF de base des événements attachés sur RoutedEvent, vous pouvez utiliser RaiseEvent pour déclencher un événement attaché à partir de n’importe quel UIElement ou ContentElement. Le déclenchement d’un événement routé (attaché ou non) nécessite que vous déclariez un élément particulier dans l’arborescence d’éléments en tant que source d’événement ; cette source est signalée en tant qu’appelant RaiseEvent . Votre service est chargé de déterminer quel est l’élément signalé en tant que source dans l’arborescence

Voir aussi