Partager via


Guide pratique pour ajouter la gestion des classes pour un événement routé

Les événements routés peuvent être gérés par des gestionnaires de classes ou des gestionnaires d’instances sur n’importe quel nœud donné dans l’itinéraire. Les gestionnaires de classes sont appelés en premier et peuvent être utilisés par les implémentations de classes pour supprimer les événements de la gestion des instances ou introduire d’autres comportements spécifiques aux événements appartenant à des classes de base. Cet exemple illustre deux techniques étroitement liées à l’implémentation de gestionnaires de classes.

Exemple

Cet exemple utilise une classe personnalisée basée sur le panneau Canvas. Le principe de base de l'application est que la classe personnalisée introduit des comportements sur ses éléments enfants, notamment en interceptant les clics du bouton gauche de la souris et en les marquant comme traités, avant que la classe d'élément enfant ou les gestionnaires d'instances sur celle-ci ne soient appelés.

La classe UIElement expose une méthode virtuelle qui permet la gestion des classes sur l’événement PreviewMouseLeftButtonDown, en remplaçant simplement l’événement. Il s’agit du moyen le plus simple d’implémenter la gestion des classes si une telle méthode virtuelle est disponible quelque part dans la hiérarchie de votre classe. Le code suivant montre l’implémentation OnPreviewMouseLeftButtonDown dans le « MyEditContainer » dérivé de Canvas. L’implémentation marque l’événement comme géré dans les arguments, puis ajoute du code pour donner à l’élément source une modification visible de base.

protected override void OnPreviewMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
    e.Handled = true; //suppress the click event and other leftmousebuttondown responders
    MyEditContainer ec = (MyEditContainer)e.Source;
    if (ec.EditState)
    { ec.EditState = false; }
    else
    { ec.EditState = true; }
    base.OnPreviewMouseRightButtonDown(e);
}
Protected Overrides Sub OnPreviewMouseRightButtonDown(ByVal e As System.Windows.Input.MouseButtonEventArgs)
    e.Handled = True 'suppress the click event and other leftmousebuttondown responders
    Dim ec As MyEditContainer = CType(e.Source, MyEditContainer)
    If ec.EditState Then
        ec.EditState = False
    Else
        ec.EditState = True
    End If
    MyBase.OnPreviewMouseRightButtonDown(e)
End Sub

Si aucune machine virtuelle n’est disponible sur les classes de base ou pour cette méthode particulière, la gestion des classes peut être ajoutée directement à l’aide d’une méthode utilitaire de la classe EventManager, RegisterClassHandler. Cette méthode ne doit être appelée que dans l’initialisation statique des classes qui ajoutent la gestion des classes. Cet exemple ajoute un autre gestionnaire pour PreviewMouseLeftButtonDown , et dans ce cas, la classe inscrite est la classe personnalisée. En revanche, lors de l’utilisation des machines virtuelles, la classe inscrite est vraiment la classe de base UIElement. Dans les cas où les classes de base et les sous-classes enregistrent chacune un gestionnaire, les gestionnaires des sous-classes sont appelés en premier. Le comportement d'une application serait que ce gestionnaire affiche d'abord sa boîte de message, et ensuite que le changement visuel dans le gestionnaire de la méthode virtuelle soit affiché.

static MyEditContainer()
{
  EventManager.RegisterClassHandler(typeof(MyEditContainer), PreviewMouseRightButtonDownEvent, new RoutedEventHandler(LocalOnMouseRightButtonDown));
}
internal static void LocalOnMouseRightButtonDown(object sender, RoutedEventArgs e)
{
  MessageBox.Show("this is invoked before the On* class handler on UIElement");
  //e.Handled = true; //uncommenting this would cause ONLY the subclass' class handler to respond
}
Shared Sub New()
    EventManager.RegisterClassHandler(GetType(MyEditContainer), PreviewMouseRightButtonDownEvent, New RoutedEventHandler(AddressOf LocalOnMouseRightButtonDown))
End Sub
Friend Shared Sub LocalOnMouseRightButtonDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
    MessageBox.Show("this is invoked before the On* class handler on UIElement")
    'e.Handled = True //uncommenting this would cause ONLY the subclass' class handler to respond
End Sub

Voir aussi