Marquage des événements routés comme étant gérés et gestion de classeMarking Routed Events as Handled, and Class Handling

Les gestionnaires d’un événement routé peuvent marquer l’événement comme étant géré dans les données d’événement.Handlers for a routed event can mark the event handled within the event data. La gestion de l’événement a pour effet de raccourcir efficacement l’itinéraire.Handling the event will effectively shorten the route. La gestion de classe est un concept de programmation pris en charge par les événements routés.Class handling is a programming concept that is supported by routed events. Un gestionnaire de classe peut gérer un événement routé particulier au niveau d’une classe à l’aide d’un gestionnaire appelé avant tout gestionnaire d’instance sur une instance de la classe.A class handler has the opportunity to handle a particular routed event at a class level with a handler that is invoked before any instance handler on any instance of the class.

PrérequisPrerequisites

Cette rubrique décrit plus en détail les concepts introduits dans Vue d’ensemble des événements routés.This topic elaborates on concepts introduced in the Routed Events Overview.

Quand marquer des événements comme étant gérésWhen to Mark Events as Handled

Lorsque vous affectez à Handled true la propriété la valeur dans les données d’événement pour un événement routé, on parle de «marquage de l’événement géré».When you set the value of the Handled property to true in the event data for a routed event, this is referred to as "marking the event handled". Que vous soyez auteur d’une application ou auteur d’un contrôle qui répond à des événements routés existants ou qui implémente de nouveaux événements routés, il n’existe aucune règle absolue qui indique à quel moment marquer les événements routés comme étant gérés.There is no absolute rule for when you should mark routed events as handled, either as an application author, or as a control author who responds to existing routed events or implements new routed events. Dans la plupart des cas, le concept de «géré», tel qu’il est inclus dans les données d’événement de l’événement routé, doit être utilisé comme un protocole limité pour les réponses de votre propre application WPFWPF aux divers événements routés exposés dans les API, ainsi que pour tous les événements routés personnalisés.For the most part, the concept of "handled" as carried in the routed event's event data should be used as a limited protocol for your own application's responses to the various routed events exposed in WPFWPF APIs as well as for any custom routed events. Une autre façon d’envisager la question du marquage « géré » est que vous devez généralement marquer un événement routé comme étant géré si votre code a répondu à l’événement routé d’une manière significative et relativement complète.Another way to consider the "handled" issue is that you should generally mark a routed event handled if your code responded to the routed event in a significant and relatively complete way. En règle générale, il ne doit pas exister plus d’une réponse significative à exiger des implémentations de gestionnaire distinctes pour une même occurrence d’événement routé.Typically, there should not be more than one significant response that requires separate handler implementations for any single routed event occurrence. Si plusieurs réponses sont nécessaires, le code correspondant doit être implémenté à travers la logique d’application intégrée à un gestionnaire unique plutôt qu’en utilisant le système d’événement routé pour le transfert.If more responses are needed, then the necessary code should be implemented through application logic that is chained within a single handler rather than by using the routed event system for forwarding. L’idée de ce qui est « significatif » revêt aussi une dimension subjective et dépend de votre application ou de votre code.The concept of what is "significant" is also subjective, and depends on your application or code. À titre d’indication générale, voici quelques exemples de « réponses significatives » : définition du focus, modification de l’état public, définition des propriétés qui affectent la représentation visuelle et déclenchement d’autres événements nouveaux.As general guidance, some "significant response" examples include: setting focus, modifying public state, setting properties that affect the visual representation, and raising other new events. À l’inverse, la modification de l’état privé (sans impact visuel ni représentation de programmation), la journalisation d’événements ou la consultation des arguments d’un événement et la décision de ne pas y répondre sont des exemples de réponses non significatives.Examples of nonsignificant responses include: modifying private state (with no visual impact, or programmatic representation), logging of events, or looking at arguments of an event and choosing not to respond to it.

Le comportement du système d’événements routé renforce ce modèle de «réponse significative» pour l’utilisation de l’état géré d’un événement routé, car les XAMLXAML gestionnaires ajoutés dans ou la AddHandler signature commune de ne sont pas appelés en réponse à un événement routé où l’événement les données sont déjà marquées comme étant gérées.The routed event system behavior reinforces this "significant response" model for using handled state of a routed event, because handlers added in XAMLXAML or the common signature of AddHandler are not invoked in response to a routed event where the event data is already marked handled. Vous devez faire le nécessaire pour ajouter un gestionnaire avec la handledEventsToo version de paramètre (AddHandler(RoutedEvent, Delegate, Boolean)) afin de gérer les événements routés qui sont marqués comme gérés par des participants antérieurs dans l’itinéraire d’événement.You must go through the extra effort of adding a handler with the handledEventsToo parameter version (AddHandler(RoutedEvent, Delegate, Boolean)) in order to handle routed events that are marked handled by earlier participants in the event route.

Dans certains cas, les contrôles proprement dits marquent certains événements routés comme étant gérés.In some circumstances, controls themselves mark certain routed events as handled. Un événement routé géré représente une décision de la part des auteurs d’un contrôle WPFWPF que les actions du contrôle en réponse à l’événement routé sont significatives ou terminées dans le cadre de l’implémentation du contrôle, et l’événement n’a plus besoin d’être géré.A handled routed event represents a decision by WPFWPF control authors that the control's actions in response to the routed event are significant or complete as part of the control implementation, and the event needs no further handling. Cela consiste généralement à ajouter un gestionnaire de classe pour un événement ou à remplacer l’un des virtuels de gestionnaire de classe qui existent dans une classe de base.Usually this is done by adding a class handler for an event, or by overriding one of the class handler virtuals that exist on a base class. Vous pouvez toujours contourner cette gestion d’événement, si nécessaire ; consultez la page Résolution des problèmes liés à la suppression d’événements par des contrôles plus loin dans cette rubrique.You can still work around this event handling if necessary; see Working Around Event Suppression by Controls later in this topic.

Événements Preview (tunneling) versus événements de propagation et gestion des événements"Preview" (Tunneling) Events vs. Bubbling Events, and Event Handling

Les événements routés Preview sont des événements qui suivent un itinéraire de tunneling dans l’arborescence des éléments.Preview routed events are events that follow a tunneling route through the element tree. « Preview », exprimé dans la convention de nommage, est révélateur du principe général des événements d’entrée selon lequel les événements routés Preview (tunneling) sont déclenchés avant l’événement routé de propagation équivalent.The "Preview" expressed in the naming convention is indicative of the general principle for input events that preview (tunneling) routed events are raised prior to the equivalent bubbling routed event. Par ailleurs, les événements routés d’entrée associés à une paire de tunneling et de propagation ont une logique de gestion distincte.Also, input routed events that have a tunneling and bubbling pair have a distinct handling logic. Si l’événement routé de tunneling/preview est marqué comme étant géré par un écouteur d’événements, l’événement routé de propagation est alors marqué comme étant géré, avant même qu’un écouteur de l’événement routé de propagation l’ait reçu.If the tunneling/preview routed event is marked as handled by an event listener, then the bubbling routed event will be marked handled even before any listeners of the bubbling routed event receive it. Les événements routés de tunneling et de propagation sont des événements techniquement distincts, mais ils partagent délibérément la même instance de données d’événement pour autoriser ce comportement.The tunneling and bubbling routed events are technically separate events, but they deliberately share the same instance of event data to enable this behavior.

La connexion entre les événements routés de tunneling et de propagation est établie par l’implémentation interne du mode de déclenchement des événements routés déclarés d’une classe WPFWPF donnée, et cela s’applique aux événements routés d’entrée associés.The connection between the tunneling and bubbling routed events is accomplished by the internal implementation of how any given WPFWPF class raises its own declared routed events, and this is true of the paired input routed events. Cependant, à moins que cette implémentation au niveau de la classe existe, aucune connexion n’est établie entre un événement routé de tunneling et un événement routé de propagation qui partagent le modèle de nommage : sans cette implémentation, ils deviendraient deux événements routés totalement distincts et ne seraient pas déclenchés dans l’ordre, ni ne partageraient les données d’événement.But unless this class-level implementation exists, there is no connection between a tunneling routed event and a bubbling routed event that share the naming scheme: without such implementation they would be two entirely separate routed events and would not be raised in sequence or share event data.

Pour plus d’informations sur l’implémentation des paires d’événements routés d’entrée de tunneling/propagation dans une classe personnalisée, consultez Créer un événement routé personnalisé.For more information about how to implement tunnel/bubble input routed event pairs in a custom class, see Create a Custom Routed Event.

Gestionnaires de classe et gestionnaires d’instanceClass Handlers and Instance Handlers

Les événements routés reconnaissent deux types d’écouteur d’événement : les écouteurs de classe et les écouteurs d’instance.Routed events consider two different types of listeners to the event: class listeners and instance listeners. Les écouteurs de classe existent, car les types ont EventManager appelé uneRegisterClassHandlerAPI particulière,, dans leur constructeur statique, ou ont substitué une méthode virtuelle de gestionnaire de classe à partir d’une classe de base d’élément.Class listeners exist because types have called a particular EventManager API ,RegisterClassHandler, in their static constructor, or have overridden a class handler virtual method from an element base class. Les écouteurs d’instance sont des instances de classe/éléments particuliers dans lesquels un ou plusieurs gestionnaires ont été attachés pour cet événement routé par AddHandlerun appel à.Instance listeners are particular class instances/elements where one or more handlers have been attached for that routed event by a call to AddHandler. Les WPFWPF événements routés existants effectuent AddHandler des appels à dans le cadre du wrapper d’événement Common Language Runtime{} (CLR{} ) ajouter et supprimer des implémentations de l’événement, qui XAMLXAML est également la manière dont le mécanisme simple de l’attachement de gestionnaires d’événements via une syntaxe d’attribut est activé.Existing WPFWPF routed events make calls to AddHandler as part of the common language runtime (CLR) event wrapper add{} and remove{} implementations of the event, which is also how the simple XAMLXAML mechanism of attaching event handlers via an attribute syntax is enabled. Par conséquent, même XAMLXAML l’utilisation simple équivaut finalement à AddHandler un appel.Therefore even the simple XAMLXAML usage ultimately equates to an AddHandler call.

Les éléments de l’arborescence d’éléments visuels sont vérifiés pour déterminer s’ils comportent des implémentations de gestionnaire enregistré.Elements within the visual tree are checked for registered handler implementations. Les gestionnaires sont potentiellement appelés tout au long de l’itinéraire, dans l’ordre inhérent au type de la stratégie de routage pour cet événement routé.Handlers are potentially invoked throughout the route, in the order that is inherent in the type of the routing strategy for that routed event. Par exemple, les événements routés de propagation appellent d’abord les gestionnaires associés à l’élément qui a déclenché l’événement routé.For instance, bubbling routed events will first invoke those handlers that are attached to the same element that raised the routed event. Les événements routés sont ensuite « propagés » au prochain élément parent, et ainsi de suite jusqu’à ce que l’élément racine de l’application soit atteint.Then the routed event "bubbles" to the next parent element and so on until the application root element is reached.

Du point de vue de l’élément racine d’un itinéraire de propagation, si la gestion de classe ou tout élément plus proche de la source de l’événement routé appelle des gestionnaires qui marquent les arguments d’événement comme étant gérés, les gestionnaires des éléments racine ne sont pas appelés, et l’itinéraire de l’événement est raccourci efficacement avant d’atteindre l’élément racine en question.From the perspective of the root element in a bubbling route, if class handling or any element closer to the source of the routed event invoke handlers that mark the event arguments as being handled, then handlers on the root elements are not invoked, and the event route is effectively shortened before reaching that root element. Cependant, l’itinéraire n’est pas complètement arrêté, car il est possible d’ajouter des gestionnaires à l’aide d’un conditionnel spécial qui exige qu’ils soient tout de même appelés, même si un gestionnaire de classe ou d’instance a marqué l’événement routé comme étant géré.However, the route is not completely halted, because handlers can be added using a special conditional that they should still be invoked, even if a class handler or instance handler has marked the routed event as handled. Cet aspect est détaillé plus loin dans cette rubrique dans Ajout de gestionnaires d’instance déclenchés y compris quand les événements sont marqués comme étant gérés.This is explained in Adding Instance Handlers That Are Raised Even When Events Are Marked Handled, later in this topic.

À un niveau plus approfondi que l’itinéraire d’événement se trouvent également des gestionnaires de classe potentiellement multiples qui agissent sur une instance donnée d’une classe.At a deeper level than the event route, there are also potentially multiple class handlers acting on any given instance of a class. Cela est dû au fait que le modèle de gestion de classe des événements routés permet à toutes les classes possibles d’une hiérarchie de classes d’enregistrer chacune son propre gestionnaire de classe pour chaque événement routé.This is because the class handling model for routed events enables all possible classes in a class hierarchy to each register its own class handler for each routed event. Chaque gestionnaire de classe est ajouté à un magasin interne, et quand l’itinéraire d’événement d’une application est construit, les gestionnaires de classe sont tous ajoutés à l’itinéraire d’événement.Each class handler is added to an internal store, and when the event route for an application is constructed, the class handlers are all added to the event route. Les gestionnaires de classe sont ajoutés à l’itinéraire de sorte que le gestionnaire de classe le plus dérivé soit appelé en premier et que les gestionnaires de chaque classe de base consécutive soient appelés ensuite.Class handlers are added to the route such that the most-derived class handler is invoked first, and class handlers from each successive base class are invoked next. En règle générale, les gestionnaires de classe ne sont pas enregistrés de sorte qu’ils répondent aussi aux événements routés qui étaient déjà marqués comme étant gérés.Generally, class handlers are not registered such that they also respond to routed events that were already marked handled. Par conséquent, ce mécanisme de gestion de classe permet d’opter pour l’un des deux choix suivants :Therefore, this class handling mechanism enables one of two choices:

  • Les classes dérivées peuvent compléter la gestion de classe héritée de la classe de base en ajoutant un gestionnaire qui ne marque pas l’événement routé comme étant géré, car le gestionnaire de classe de base sera appelé peu de temps après le gestionnaire de classe dérivé.Derived classes can supplement the class handling that is inherited from the base class by adding a handler that does not mark the routed event handled, because the base class handler will be invoked sometime after the derived class handler.

  • Les classes dérivées peuvent remplacer la gestion de classe à partir de la classe de base en ajoutant un gestionnaire de classe qui marque l’événement routé comme étant géré.Derived classes can replace the class handling from the base class by adding a class handler that marks the routed event handled. Vous devez être prudent avec cette approche, car elle est susceptible de changer la conception du contrôle de base prévu dans des domaines tels que l’apparence visuelle, la logique d’état, la gestion des entrées et la gestion des commandes.You should be cautious with this approach, because it will potentially change the intended base control design in areas such as visual appearance, state logic, input handling, and command handling.

Gestion de classe des événements routés par les classes de base de contrôleClass Handling of Routed Events by Control Base Classes

Sur chaque nœud d’élément donné au sein d’un itinéraire d’événement, les écouteurs de classe peuvent répondre à l’événement routé avant n’importe quel écouteur d’instance de l’élément.On each given element node in an event route, class listeners have the opportunity to respond to the routed event before any instance listener on the element can. C’est pourquoi les gestionnaires de classe sont parfois utilisés pour supprimer les événements routés qu’une implémentation de classe de contrôle particulière ne souhaite pas propager davantage, ou pour assurer une gestion spéciale de l’événement routé qui compte parmi les fonctionnalités de la classe.For this reason, class handlers are sometimes used to suppress routed events that a particular control class implementation does not wish to propagate further, or to provide special handling of that routed event that is a feature of the class. Par exemple, une classe peut déclencher son propre événement spécifique qui contient davantage de détails sur la signification de la condition d’entrée utilisateur dans le contexte de cette classe particulière.For instance, a class might raise its own class-specific event that contains more specifics about what some user input condition means in the context of that particular class. L’implémentation de classe peut ensuite marquer l’événement routé plus général comme étant géré.The class implementation might then mark the more general routed event as handled. Les gestionnaires de classe sont généralement ajoutés de sorte qu’ils ne sont pas appelés pour les événements routés où les données d’événement partagées étaient déjà marquées comme étant gérées, mais pour les cas atypiques, il existe également une RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) signature qui inscrit les gestionnaires de classe à appeler même lorsque les événements routés sont marqué comme géré.Class handlers are typically added such that they are not invoked for routed events where shared event data was already marked handled, but for atypical cases there is also a RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) signature that registers class handlers to invoke even when routed events are marked handled.

Virtuels de gestionnaire de classeClass Handler Virtuals

Certains éléments, en particulier les éléments de base UIElementtels que, exposent des méthodes virtuelles vides*«on * Event» et «OnPreview Event» qui correspondent à leur liste d’événements routés publics.Some elements, particularly the base elements such as UIElement, expose empty "On*Event" and "OnPreview*Event" virtual methods that correspond to their list of public routed events. Ces méthodes virtuelles peuvent être remplacées de façon à implémenter un gestionnaire de classe pour l’événement routé en question.These virtual methods can be overridden to implement a class handler for that routed event. Les classes d’éléments de base inscrivent ces méthodes virtuelles en tant que gestionnaire de classe pour RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) chacun de ces événements routés à l’aide de, comme décrit précédemment.The base element classes register these virtual methods as their class handler for each such routed event using RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) as described earlier. Les méthodes virtuelles On*Event facilitent considérablement l’implémentation de la gestion de classe pour les événements routés correspondants, sans nécessiter d’initialisation spéciale dans les constructeurs statiques de chaque type.The On*Event virtual methods make it much simpler to implement class handling for the relevant routed events, without requiring special initialization in static constructors for each type. Par exemple, vous pouvez ajouter la gestion de classe DragEnter pour l’événement UIElement dans toute classe dérivée en OnDragEnter substituant la méthode virtuelle.For instance, you can add class handling for the DragEnter event in any UIElement derived class by overriding the OnDragEnter virtual method. Au cours de ce remplacement, vous pouvez gérer l’événement routé, déclencher d’autres événements, initialiser la logique spécifique à la classe qui pourrait changer des propriétés d’élément dans les instances, ou toute combinaison de ces actions.Within the override, you could handle the routed event, raise other events, initiate class-specific logic that might change element properties on instances, or any combination of those actions. En règle générale, dans ce type de modification, vous devez appeler l’implémentation de base même si vous marquez l’événement comme étant géré.You should generally call the base implementation in such overrides even if you mark the event handled. Il est vivement recommandé d’appeler l’implémentation de base, car la méthode virtuelle se trouve au niveau de la classe de base.Calling the base implementation is strongly recommended because the virtual method is on the base class. Dans l’absolu, le modèle virtuel protégé standard mis en œuvre pour appeler les implémentations de base à partir de chaque virtuel remplace et met en parallèle un mécanisme similaire natif de la gestion des classes d’événements routés, au moyen duquel sont appelés les gestionnaires de toutes les classes d’une hiérarchie de classes d’une instance donnée, en commençant par le gestionnaire de classe le plus dérivé pour ensuite passer au gestionnaire de classe de base.The standard protected virtual pattern of calling the base implementations from each virtual essentially replaces and parallels a similar mechanism that is native to routed event class handling, whereby class handlers for all classes in a class hierarchy are called on any given instance, starting with the most-derived class' handler and continuing to the base class handler. Vous ne devez omettre l’appel à l’implémentation de base que si votre classe exige délibérément de changer la logique de gestion de classe de base.You should only omit the base implementation call if your class has a deliberate requirement to change the base class handling logic. C’est la nature de votre implémentation qui détermine si vous appelez l’implémentation de base avant ou après votre code de substitution.Whether you call the base implementation before or after your overriding code will depend on the nature of your implementation.

Gestion des classes d’événements d’entréeInput Event Class Handling

Les méthodes virtuelles des gestionnaires de classe sont toutes enregistrées pour faire en sorte qu’elles ne soient appelées que si les données d’événement partagées ne sont pas déjà marquées comme étant gérées.The class handler virtual methods are all registered such that they are only invoked in cases where any shared event data are not already marked handled. Par ailleurs, pour les événements d’entrée uniquement, les versions de tunneling et de propagation sont généralement déclenchées dans l’ordre et partagent les données d’événement.Also, for the input events uniquely, the tunneling and bubbling versions typically are raised in sequence and share event data. Par conséquent, pour une paire donnée de gestionnaires de classe d’événements d’entrée, où l’un correspond à la version de tunneling et l’autre à la version de propagation, vous pouvez ne pas marquer immédiatement l’événement comme étant géré.This entails that for a given pair of class handlers of input events where one is the tunneling version and the other is the bubbling version, you may not want to mark the event handled immediately. Si vous implémentez la méthode virtuelle de gestion de classe par tunneling pour marquer l’événement comme étant géré, le gestionnaire de classe de propagation ne pourra pas être appelé (ni même les gestionnaires d’instance enregistrés normalement pour l’événement de tunneling ou de propagation).If you implement the tunneling class handling virtual method to mark the event handled, that will prevent the bubbling class handler from being invoked (as well as preventing any normally registered instance handlers for either the tunneling or bubbling event from being invoked).

Une fois que la gestion de classe est terminée sur un nœud, les écouteurs d’instance sont pris en considération.Once class handling on a node is complete, the instance listeners are considered.

Ajout de gestionnaires d’instance déclenchés y compris quand les événements sont marqués comme étant gérésAdding Instance Handlers That Are Raised Even When Events Are Marked Handled

La AddHandler méthode fournit une surcharge particulière qui vous permet d’ajouter des gestionnaires qui seront appelés par le système d’événements chaque fois qu’un événement atteint l’élément de gestion dans l’itinéraire, même si un autre gestionnaire a déjà ajusté les données d’événement pour marquer ce événement comme géré.The AddHandler method supplies a particular overload that allows you to add handlers that will be invoked by the event system whenever an event reaches the handling element in the route, even if some other handler has already adjusted the event data to mark that event as handled. Il ne s’agit pas de la procédure courante.This is not typically done. En général, des gestionnaires peuvent être écrits pour ajuster toutes les zones de code d’application susceptibles d’être influencées par un événement, indépendamment de l’emplacement où il a été géré dans une arborescence d’éléments, même si plusieurs résultats finaux sont souhaités.Generally, handlers can be written to adjust all areas of application code that might be influenced by an event, regardless of where it was handled in an element tree, even if multiple end results are desired. De plus, seul un élément est généralement chargé véritablement de répondre à cet événement, et la logique d’application appropriée s’est déjà exécutée.Also, typically there is really only one element that needs to respond to that event, and the appropriate application logic had already happened. Cependant, la surcharge handledEventsToo est disponible pour les cas exceptionnels où un autre élément d’une arborescence d’éléments ou une composition de contrôles a déjà marqué un événement comme étant géré, mais que d’autres éléments situés plus haut ou plus bas dans l’arborescence d’éléments (en fonction de l’itinéraire) demandent toujours à ce que leurs propres gestionnaires soient appelés.But the handledEventsToo overload is available for the exceptional cases where some other element in an element tree or control compositing has already marked an event as handled, but other elements either higher or lower in the element tree (depending on route) still wish to have their own handlers invoked.

Quand marquer des événements gérés comme étant non gérésWhen to Mark Handled Events as Unhandled

En règle générale, les événements routés marqués comme étant gérés ne doivent pas être marquésHandled comme étant non falsegérés (redéfinis sur) même handledEventsToopar les gestionnaires qui agissent.Generally, routed events that are marked handled should not be marked unhandled (Handled set back to false) even by handlers that act on handledEventsToo. Cependant, certains événements d’entrée ont des représentations d’événement de haut niveau et de bas niveau qui peuvent se chevaucher quand l’événement de haut niveau et l’événement de bas niveau ne se trouvent pas à la même position dans l’arborescence.However, some input events have high-level and lower-level event representations that can overlap when the high-level event is seen at one position in the tree and the low-level event at another position. Par exemple, considérez le cas où un élément enfant écoute un événement de clé de haut niveau, TextInput par exemple, lorsqu’un élément parent écoute un événement de bas niveau KeyDowntel que.For instance, consider the case where a child element listens to a high-level key event such as TextInput while a parent element listens to a low-level event such as KeyDown. Si l’élément parent gère l’événement de bas niveau, l’événement de haut niveau peut être supprimé même dans l’élément enfant qui logiquement devrait être le premier à pouvoir gérer l’événement.If the parent element handles the low-level event, the higher-level event can be suppressed even in the child element that intuitively should have first opportunity to handle the event.

Dans ce cas, il peut s’avérer nécessaire d’ajouter des gestionnaires aux éléments parents et enfants pour l’événement de bas niveau.In these situations it may be necessary to add handlers to both parent elements and child elements for the low-level event. L’implémentation du gestionnaire d’éléments enfants peut marquer l’événement de bas niveau comme étant géré, mais l’implémentation du gestionnaire d’éléments parents le redéfinirait comme étant non géré, si bien que les éléments de niveau supérieur de l’arborescence (ainsi que l’événement de haut niveau) peuvent avoir l’occasion de répondre.The child element handler implementation can mark the low-level event as handled, but the parent element handler implementation would set it unhandled again so that further elements up the tree (as well as the high-level event) can have the opportunity to respond. Ce cas de figure devrait être assez rare.This situation is should be fairly rare.

Suppression délibérée d’événements d’entrée pour la composition de contrôlesDeliberately Suppressing Input Events for Control Compositing

La gestion de classe d’événements routés est principalement utilisée pour les événements d’entrée et les contrôles composés.The main scenario where class handling of routed events is used is for input events and composited controls. Un contrôle composé est par définition composé de plusieurs contrôles pratiques ou classes de base de contrôle.A composited control is by definition composed of multiple practical controls or control base classes. Souvent, l’intention de l’auteur du contrôle est d’amalgamer tous les événements d’entrée possibles que chaque sous-composant peut déclencher, de façon à signaler l’ensemble du contrôle comme étant la source singulière des événements.Often the author of the control wishes to amalgamate all of the possible input events that each of the subcomponents might raise, in order to report the entire control as the singular event source. Dans certains cas, l’auteur du contrôle peut souhaiter supprimer totalement les événements des composants ou remplacer un événement défini par un composant qui contient davantage d’informations ou implique un comportement plus spécifique.In some cases the control author might wish to suppress the events from components entirely, or substitute a component-defined event that carries more information or implies a more specific behavior. L’exemple canonique qui est immédiatement visible par l’auteur d’un composant est Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) la manière dont a Button gère tout événement de souris qui finit par se résoudre en un événement intuitif Click que tous les boutons ont: un événement.The canonical example that is immediately visible to any component author is how a Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) Button handles any mouse event that will eventually resolve to the intuitive event that all buttons have: a Click event.

La Button classe de baseButtonBase() Control dérive de qui dérive à son FrameworkElement tour UIElementde et, et la plus grande partie de l’infrastructure d’événements nécessaire pour le UIElement traitement d’entrée de contrôle est disponible au niveau du.The Button base class (ButtonBase) derives from Control which in turn derives from FrameworkElement and UIElement, and much of the event infrastructure needed for control input processing is available at the UIElement level. En particulier, UIElement traite les Mouse événements généraux qui gèrent le test de positionnement pour le curseur de la souris dans ses limites et fournit des événements distincts pour les actions de bouton MouseLeftButtonDownles plus courantes, telles que.In particular, UIElement processes general Mouse events that handle hit testing for the mouse cursor within its bounds, and provides distinct events for the most common button actions, such as MouseLeftButtonDown. UIElementfournit également un virtuel OnMouseLeftButtonDown vide comme gestionnaire de classe préinscrit pour MouseLeftButtonDownet ButtonBase le remplace.UIElement also provides an empty virtual OnMouseLeftButtonDown as the preregistered class handler for MouseLeftButtonDown, and ButtonBase overrides it. De même, ButtonBase utilise des gestionnaires de classe MouseLeftButtonUppour.Similarly, ButtonBase uses class handlers for MouseLeftButtonUp. Dans les substitutions, qui sont passées aux données d’événement, les implémentations marquent RoutedEventArgs cette instance comme gérée Handled en trueaffectant à la valeur, et ces mêmes données d’événement se poursuivent le long du reste de l’itinéraire vers d’autres gestionnaires de classe et également pour les gestionnaires d’instances ou les accesseurs set d’événement.In the overrides, which are passed the event data, the implementations mark that RoutedEventArgs instance as handled by setting Handled to true, and that same event data is what continues along the remainder of the route to other class handlers and also to instance handlers or event setters. En outre, OnMouseLeftButtonUp le remplacement déclenchera ensuite l' Click événement.Also, the OnMouseLeftButtonUp override will next raise the Click event. Le résultat final pour la plupart des écouteurs est que les MouseLeftButtonDown événements MouseLeftButtonUp et «disparaissent» et sont remplacés plutôt Clickpar, un événement qui a plus de sens, car il est connu que cet événement provient d’un vrai bouton et pas d’une certaine pièce composite du bouton ou d’un autre élément entièrement.The end result for most listeners will be that the MouseLeftButtonDown and MouseLeftButtonUp events "disappear" and are replaced instead by Click, an event that holds more meaning because it is known that this event originated from a true button and not some composite piece of the button or from some other element entirely.

Résolution des problèmes liés à la suppression d’événements par des contrôlesWorking Around Event Suppression by Controls

Ce comportement de suppression d’événements au sein des contrôles individuels peut parfois interférer avec certaines intentions plus générales de la logique de gestion des événements de votre application.Sometimes this event suppression behavior within individual controls can interfere with some more general intentions of event handling logic for your application. Par exemple, si, pour une raison ou une autre, votre MouseLeftButtonDown application a un gestionnaire localisé au niveau de l’élément racine de l’application, vous remarquerez que MouseLeftButtonDown le MouseLeftButtonUp clic de souris sur un bouton n’appelle pas ou ne gère pas les gestionnaires au niveau de la racine.For instance, if for some reason your application had a handler for MouseLeftButtonDown located at the application root element, you would notice that any mouse click on a button would not invoke MouseLeftButtonDown or MouseLeftButtonUp handlers at the root level. L’événement proprement dit s’est bien propagé (encore une fois, les itinéraires d’événements ne se terminent pas véritablement, mais le système d’événements routés change leur comportement d’appel de gestionnaire après qu’ils ont été marqués comme étant gérés).The event itself actually did bubble up (again, event routes are not truly ended, but the routed event system changes their handler invocation behavior after being marked handled). Lorsque l’événement routé a atteint le bouton, la ButtonBase gestion de classe est MouseLeftButtonDown marquée comme gérée, car elle Click a voulu remplacer l’événement par plus de signification.When the routed event reached the button, the ButtonBase class handling marked the MouseLeftButtonDown handled because it wished to substitute the Click event with more meaning. Par conséquent, tout MouseLeftButtonDown gestionnaire standard qui se trouve plus haut dans l’itinéraire n’est pas appelé.Therefore, any standard MouseLeftButtonDown handler further up the route would not be invoked. Vous avez le choix entre deux techniques pour faire en sorte que vos gestionnaires soient appelés dans ce cas.There are two techniques you can use to ensure that your handlers would be invoked in this circumstance.

La première technique consiste à ajouter délibérément le gestionnaire handledEventsToo à l' AddHandler(RoutedEvent, Delegate, Boolean)aide de la signature de.The first technique is to deliberately add the handler using the handledEventsToo signature of AddHandler(RoutedEvent, Delegate, Boolean). La limite de cette approche vient du fait que le gestionnaire d’événements ne peut être joint qu’à partir du code et non du balisage.A limitation of this approach is that this technique for attaching an event handler is only possible from code, not from markup. La syntaxe simple de spécification du nom du gestionnaire d’événements en tant que valeur d’attribut d’événement via langage XAML (eXtensible Application Markup Language)Extensible Application Markup Language (XAML) n’active pas ce comportement.The simple syntax of specifying the event handler name as an event attribute value via langage XAML (eXtensible Application Markup Language)Extensible Application Markup Language (XAML) does not enable that behavior.

La deuxième technique vaut uniquement pour les événements d’entrée où les versions de tunneling et de propagation de l’événement routé sont associées.The second technique works only for input events, where the tunneling and bubbling versions of the routed event are paired. Pour ces événements routés, vous pouvez plutôt ajouter des gestionnaires à l’événement routé équivalent preview/tunneling équivalent.For these routed events, you can add handlers to the preview/tunneling equivalent routed event instead. Cet événement routé crée un tunnel le long de l’itinéraire en partant de la racine, si bien que le code de gestion de classe Button ne l’intercepte pas, présumant que vous avez joint le gestionnaire Preview au niveau d’un élément ancêtre dans l’arborescence d’éléments de l’application.That routed event will tunnel through the route starting from the root, so the button class handling code would not intercept it, presuming that you attached the Preview handler at some ancestor element level in the application's element tree. Si vous utilisez cette approche, faites attention quand il s’agit de marquer un événement Preview comment étant géré.If you use this approach, be cautious about marking any Preview event handled. Pour l’exemple donné avec PreviewMouseLeftButtonDown géré au niveau de l’élément racine, si vous avez marqué l' Handled événement comme dans l’implémentation du gestionnaire, vous supprimez réellement l' Click événement.For the example given with PreviewMouseLeftButtonDown being handled at the root element, if you marked the event as Handled in the handler implementation, you would actually suppress the Click event. Ce comportement n’est généralement pas souhaitable.That is typically not desirable behavior.

Voir aussiSee also