Markieren von Routingereignissen als behandelt und KlassenbehandlungMarking Routed Events as Handled, and Class Handling

Handler für ein Routingereignis können das Ereignis innerhalb der Ereignisdaten als behandelt markieren.Handlers for a routed event can mark the event handled within the event data. Das Behandeln des Ereignisses verkürzt die Route.Handling the event will effectively shorten the route. Die Klassenbehandlung ist ein Programmierkonzept, das von Routingereignissen unterstützt wird.Class handling is a programming concept that is supported by routed events. Ein Klassenhandler hat die Möglichkeit, ein bestimmtes Routingereignis auf Klassenebene mit einem Ereignishandler zu verarbeiten, der vor jedem Instanzenhandler auf jeder Instanz der Klasse aufgerufen wird.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.

Erforderliche KomponentenPrerequisites

In diesem Thema werden unter Übersicht über Routingereignisse eingeführte Konzepte näher erläutert.This topic elaborates on concepts introduced in the Routed Events Overview.

Markieren von Ereignissen als behandeltWhen to Mark Events as Handled

Wenn Sie den Wert der Handled -Eigenschaft in den Ereignisdaten für ein Routing Ereignis auf true festlegen, wird dies als "kennzeichnen des behandelten Ereignisses" bezeichnet.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". Es gibt keine absolute Regel dafür, wann Sie Routingereignisse als Anwendungsentwickler oder als Autor von Steuerelementen, der auf vorhandenen Routingereignisse reagiert oder neue Routingereignisse implementiert, als behandelt markieren sollten.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. Zum größten Teil sollte das Konzept "behandelt", das in den Ereignisdaten des Routing Ereignisses enthalten ist, als eingeschränktes Protokoll für die Antworten ihrer eigenen Anwendung auf die verschiedenen Routing Ereignisse, die in WPFWPF APIs verfügbar gemacht werden, sowie für alle benutzerdefinierten Routing Ereignisse verwendet werden.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. Eine weitere Möglichkeit, das Problem als „behandelt“ zu markieren ist, wenn Code auf eine Weise signifikant und relativ vollständig auf das Routingereignis geantwortet hat.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. In der Regel sollte es nicht mehr als eine signifikante Antwort geben, die separate Handlerimplementierungen für Routingereignisse erfordern muss.Typically, there should not be more than one significant response that requires separate handler implementations for any single routed event occurrence. Wenn mehr Antworten erforderlich sind, sollte der erforderliche Code über Anwendungslogik implementiert werden, die in einem einzelnen Handler, nicht mithilfe des Weiterleitungssystems des Routingereignisses verkettet ist.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. Das Konzept von „erheblich“ ist ebenfalls subjektiv und hängt von der Anwendung oder dem Code ab.The concept of what is "significant" is also subjective, and depends on your application or code. „Signifikante Antworten“ sind z.B.: das Festlegen des Fokus, die Änderung des öffentlichen Zustands, das Festlegen von Eigenschaften, die sich auf die visuelle Darstellung auswirken, und das Auslösen neuer Ereignisse.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. Beispiele für nicht signifikante Antworten sind: die Änderung des privaten Status (mit keiner visuellen Auswirkung oder eine programmgesteuerte Darstellung), das Protokollieren von Ereignissen, oder das Anzeigen eines Ereignisses und die Wahl, nicht darauf zu reagieren.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.

Das Verhalten des Routing Ereignis Systems verstärkt dieses "bedeutende Antwort Modell" für die Verwendung des behandelten Zustands eines Routing Ereignisses, da in XAMLXAML hinzugefügte Handler oder die allgemeine Signatur von AddHandler nicht als Antwort auf ein Routing Ereignis aufgerufen werden, bei dem das Ereignis die Daten sind bereits als behandelt markiert.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. Sie müssen den zusätzlichen Aufwand für das Hinzufügen eines Handlers mit handledEventsToo der Parameter VersionAddHandler(RoutedEvent, Delegate, Boolean)() durchlaufen, um Routing Ereignisse zu verarbeiten, die von früheren Teilnehmern in der Ereignis Route behandelt werden.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.

In einigen Fällen markieren Steuerelemente selbst bestimmte Routingereignisse als behandelt.In some circumstances, controls themselves mark certain routed events as handled. Mit einem behandelten Rountingereignis gibt der Autor eines WPFWPF-Steuerelements zu verstehen, dass die Antwort des Steuerelements auf das Routingereignis signifikant bzw. im Rahmen der Implementierung vollständig ist und dass das Ereignis keine weitere Behandelung benötigt.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. Dies erfolgt normalerweise durch Hinzufügen eines Klassenhandlers für ein Ereignis oder durch Überschreiben eines der virtuellen Klassenhandler, die in einer Basisklasse vorhanden sind.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. Sie können dieses Ereignisbehandlung, wenn notwendig, umgehen. Informationen dazu finden Sie weiter unten im Abschnitt Umgehen der Ereignisunterdrückung von Steuerelementen in diesem Thema.You can still work around this event handling if necessary; see Working Around Event Suppression by Controls later in this topic.

"Vorschau" (tunnelingereignisse) im Vergleich zu Blasen Ereignisse und Ereignis Behandlung"Preview" (Tunneling) Events vs. Bubbling Events, and Event Handling

Vorschaurountingereignisse sind Ereignisse, die einer Tunnelingroute in der Elementstruktur folgen.Preview routed events are events that follow a tunneling route through the element tree. Die „Vorschau“ in der Benennungskonvention weist auf das allgemeine Prinzip bei Eingabeereignissen hin, nach dem Vorschau-/ Tunneling-Routingereignisse vor den entsprechenden Bubbling-Rountingereignissen ausgelöst werden.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. Außerdem haben Eingaberountingereignisse mit einem Tunneling- und einem Bubblingereignis eine andere Behandlungslogik.Also, input routed events that have a tunneling and bubbling pair have a distinct handling logic. Wenn das Tunneling-/ Vorschauroutingereignis von einem Ereignislistener als behandelt markiert wurde, dann wird das Bubblingereignis als behandelt markiert, noch bevor alle Listener des Bubblingereignisses es erhalten.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. Die Tunneling- und Bubblingroutingereignisse sind technisch separate Ereignisse. Sie teilen sich aber absichtlich dieselbe Ereignisdateninstanz, um dieses Verhalten zu ermöglichen.The tunneling and bubbling routed events are technically separate events, but they deliberately share the same instance of event data to enable this behavior.

Die Verbindung zwischen Tunneling- und Bubbling-Rountingereignissen wird mithilfe der internen Implementierung erreicht, die angibt, wie jede gegebene WPFWPF-Klasse die eigenen deklarierten Routingereignisse auslöst. Dies gilt für alle gekoppelten Eingaberountingereignisse.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. Es besteht keine Verbindung zwischen einem Tunneling- und einem Bubbling-Routnigereignis, die dasselbe Benennungsschema nutzen, wenn diese Implementierung auf Klassenebene nicht vorhanden: Ohne diese Implementierung wären beide Routingereignisse zwei vollständig getrennt und würden weder in der Sequenz ausgelöst werden, noch dieselben Ereignisdaten haben.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.

Weitere Informationen dazu, wie Sie Tunneling-/Bubbling-Eingabeereignispaare in einer benutzerdefinierten Klasse implementieren, finden Sie unter Erstellen eines benutzerdefinierten Routingereignisses.For more information about how to implement tunnel/bubble input routed event pairs in a custom class, see Create a Custom Routed Event.

Klassenhandler und InstanzhandlerClass Handlers and Instance Handlers

Rountingereignisse sollten Sie zwei verschiedene Arten von Ereignislistenern beachten: Klassenlistener und Instanzlistener.Routed events consider two different types of listeners to the event: class listeners and instance listeners. Klassenlistener existieren, weil Typen eine bestimmte EventManager API,RegisterClassHandler, in Ihrem statischen Konstruktor aufgerufen haben oder eine virtuelle Klassen Handler-Methode von einer Element Basisklasse überschrieben haben.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. Instanzlistener sind bestimmte Klassen Instanzen/-Elemente, bei denen mindestens ein Handler für dieses Routing Ereignis durch einen-Rückruf AddHandlerangefügt wurde.Instance listeners are particular class instances/elements where one or more handlers have been attached for that routed event by a call to AddHandler. Vorhandene WPFWPF Routing Ereignisse machen Aufrufe an AddHandler als Teil der Common Language Runtime (CLR)-Ereignis Wrapper Add{} -und{} remove-Implementierungen des Ereignisses, das auch den einfachen XAMLXAML Mechanismus von das Anfügen von Ereignis Handlern über eine Attribut Syntax ist aktiviert.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. Daher entspricht auch die XAMLXAML einfache Verwendung letztendlich einem AddHandler -Rückruf.Therefore even the simple XAMLXAML usage ultimately equates to an AddHandler call.

Elemente innerhalb der visuellen Struktur werden auf registrierte Handlerimplementierungen überprüft.Elements within the visual tree are checked for registered handler implementations. Handler werden möglicherweise in der gesamten Route aufgerufen, und zwar in der Reihenfolge, die im Typ der Routingstrategie für das Routingereignis inhärent ist.Handlers are potentially invoked throughout the route, in the order that is inherent in the type of the routing strategy for that routed event. Bubbling-Routingereignisse rufen z.B. zuerst die Handler auf, die dem gleichen Element zugeordnet sind, das das Routingereignis ausgelöst hat.For instance, bubbling routed events will first invoke those handlers that are attached to the same element that raised the routed event. Das Routingereignis bubblet dann zu dem nächsten übergeordneten Element und so weiter, bis das Stammelement der Anwendung erreicht ist.Then the routed event "bubbles" to the next parent element and so on until the application root element is reached.

Wenn aus der Perspektive des Stammelements in einer Bubblingroute die Klassenbehandlung oder ein beliebiges Element, das sich näher an der Quelle des Routingereignisses befindet, Handler aufrufen, die die Ereignisargumente als behandelt markieren, werden Handler in den Stammelementen nicht aufgerufen, und die Ereignisroute wird effektiv verkürzt, bevor das Stammelement erreicht wird.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. Die Route wird jedoch nicht vollständig angehalten, da Handler mithilfe der bestimmten Bedingung hinzugefügt werden können, dass sie trotzdem noch aufgerufen werden sollen, auch wenn ein Klassen- oder Instanzhandler das Routingereignis als behandelt markiert hat.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. Informationen hierzu finden Sie im Abschnitt Hinzufügen von Instanzhandlern, die ausgelöst werden, obwohl Ereignisse als behandelt markiert wurden weiter unten in diesem Thema.This is explained in Adding Instance Handlers That Are Raised Even When Events Are Marked Handled, later in this topic.

Auf einer tieferen Ebene als die Ereignisroute operieren möglicherweise mehrere Klassenhandler auf jeder gegebenen Instanz einer Klasse.At a deeper level than the event route, there are also potentially multiple class handlers acting on any given instance of a class. Das liegt daran, dass das Klassenbehandlungsmodell für Routingereignisse es allen möglichen Klassen in einer Klassenhierarchie ermöglicht, einen eigenen Klassenhandler für jedes Routingereignis zu registrieren.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. Jeder Klassenhandler wird einem internen Speicher hinzugefügt, und wenn die Ereignisroute für eine Anwendung erstellt wird, werden die Klassenhandler werden alle der Ereignisroute hinzugefügt.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. Klassenhandler werden der Route so hinzugefügt, dass der am stärksten abgeleitete Klassenhandler zuerst und die Klassenhandler aus jeder nachfolgenden Basisklasse im Anschluss aufgerufen werden.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. Klassenhandler werden im Allgemeinen nicht registriert, sodass sie auch auf Routingereignisse reagieren, die bereits als behandelt markiert wurden.Generally, class handlers are not registered such that they also respond to routed events that were already marked handled. Dieser Mechanismus zur Klassenbehandlung ermöglicht eine dieser zwei Optionen:Therefore, this class handling mechanism enables one of two choices:

  • Abgeleitete Klassen können die Klassenbehandlung ergänzen, die von der Basisklasse geerbt wird, indem ein Handler hinzugefügt wird, der das Routingereignis nicht als behandelt markiert, da der Basisklassenhandler nach dem Handler der abgeleiteten Klasse aufgerufen wird.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.

  • Abgeleitete Klassen können die Klassenbehandlung der Basisklasse ersetzen, indem ein Klassenhandler hinzugefügt wird, der das Routingereignis als behandelt markiert.Derived classes can replace the class handling from the base class by adding a class handler that marks the routed event handled. Bei diesem Ansatz sollten Sie sorgfältig vorgehen, da er möglicherweise das vorgesehene Design des Basissteuerelements in Bereichen wie der visuelle Darstellung, der Zustandslogik, der Eingabeverarbeitung und der Befehlsbehandlung ändert.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.

Klassenbehandlung von Routingereignissen durch SteuerelementbasisklassenClass Handling of Routed Events by Control Base Classes

Auf jedem gegebene Elementknoten in einer Ereignisroute haben Klassenlistener die Möglichkeit, vor jedem Instanzlistener auf dem Element auf das Routingereignis zu reagieren.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. Aus diesem Grund werden Klassenhandler manchmal verwendet, um Routingereignisse zu unterdrücken, die von der Implementierung einer bestimmten Steuerelementklasse nicht weitergegeben werden sollen, oder um eine besondere Behandlung des Routingereignisses bereitzustellen, das eine Funktion der Klasse ist.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. Eine Klasse kann z.B. ein eigenes klassenspezifisches Ereignis auslösen, das weitere Details über die Bedeutung einer Benutzereingabebedingung im Kontext der jeweiligen Klasse enthält.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. Die Implementierung der Klasse kann das allgemeinere Routingereignis dann als behandelt markieren.The class implementation might then mark the more general routed event as handled. Klassen Handler werden in der Regel so hinzugefügt, dass Sie nicht für Routing Ereignisse aufgerufen werden, bei denen freigegebene Ereignisdaten bereits als behandelt markiert wurden, aber RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) für atypische Fälle gibt es auch eine Signatur, die Klassen Handler zum Aufrufen registriert, auch wenn Routing Ereignisse als behandelt markiert.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.

Virtuelle KlassenhandlerClass Handler Virtuals

Einige-Elemente, insbesondere die Basiselemente wie UIElement, machen die virtuellen Methoden "on * Event" und "*OnPreview Event" verfügbar, die Ihrer Liste der öffentlichen Routing Ereignisse entsprechen.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. Diese virtuellen Methoden können überschrieben werden, um einen Klassenhandler für dieses Routingereignis zu implementieren.These virtual methods can be overridden to implement a class handler for that routed event. Die Basiselement Klassen registrieren diese virtuellen Methoden als Klassen Handler für jedes Routing Ereignis mithilfe RegisterClassHandler(Type, RoutedEvent, Delegate, Boolean) von, wie zuvor beschrieben.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. Die virtuellen On*Event-Methoden vereinfachen die Implementierung der Klassenbehandlung für die relevanten Routingereignisse, ohne eine spezielle Initialisierung in statischen Konstruktoren für jeden Typ zu erfordern.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. Beispielsweise können Sie eine Klassen Behandlung für das DragEnter -Ereignis in einer UIElement abgeleiteten Klasse hinzufügen, indem Sie die OnDragEnter virtuelle-Methode überschreiben.For instance, you can add class handling for the DragEnter event in any UIElement derived class by overriding the OnDragEnter virtual method. In der Überschreibung können Sie das Routingereignis behandeln, andere Ereignisse auslösen, klassenspezifische Logik initialisieren, die Elementeigenschaften für Instanzen ändern kann, oder jede beliebige Kombination dieser Aktionen ausführen.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. Sie sollten die Basisimplementierung solcher Überschreibungen generell aufrufen, selbst wenn Sie das Ereignis als behandelt markieren.You should generally call the base implementation in such overrides even if you mark the event handled. Das Aufrufen der Basisimplementierung wird dringend empfohlen, da sich die virtuelle Methode in der Basisklasse befindet.Calling the base implementation is strongly recommended because the virtual method is on the base class. Das geschützte virtuelle Standardmuster, bei dem die Basisimplementierungen aus jeder virtuellen Methode aufgerufen werden, ersetzt und entspricht einem ähnlichen Mechanismus, der nativ in der Klassenbehandlung von Routingereignissen vorkommt. Dabei werden Klassenhandler für alle Klassen in einer Klassenhierarchie auf jeder Instanz aufgerufen, beginnend mit dem Handler der am stärksten abgeleiteten Klasse und anschließend mit den Handlern der Basisklasse.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. Sie sollten den Aufruf der Basisimplementierung nur weglassen, wenn Ihre Klasse eine explizite Anforderung enthält, die Logik der Basisklassenbehandlung zu ändern.You should only omit the base implementation call if your class has a deliberate requirement to change the base class handling logic. Es hängt von der Art Ihrer Implementierung ab, ob Sie die Basisimplementierung vor oder nach dem überschreibenden Code aufrufen.Whether you call the base implementation before or after your overriding code will depend on the nature of your implementation.

Klassenbehandlung von EingabeereignissenInput Event Class Handling

Virtuelle Methoden des Klassenhandlers werden alle so registriert, dass sie nur dann aufgerufen werden, wenn gemeinsam genutzte Ereignisdaten nicht bereits als behandelt markiert wurden.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. Außerdem werden nur bei Eingabeereignissen die Tunneling- und Bubblingversionen in der Regel nacheinander ausgelöst und verwenden dieselben Ereignisdaten.Also, for the input events uniquely, the tunneling and bubbling versions typically are raised in sequence and share event data. Dazu sollten Sie ein Ereignis für ein bestimmtes Paar von Eingabeereignis-Klassenhandlern, von denen einer die Tunneling-und der andere die Bubblingversion darstellt, nicht sofort als behandelt markieren.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. Wenn Sie die virtuelle Methode der Tunneling-Klassenbehandlung implementieren, um das Ereignis als behandelt zu markieren, wird der Bubbling-Klassenhandler daran gehindert, aufgerufen zu werden (außerdem wird verhindert, dass alle normal registrierten Instanzhandler für das Tunneling- oder das Bubblingereignis aufgerufen werden).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).

Nach Abschluss der Klassenbehandlung für einen Knoten werden die Instanzlistener berücksichtigt.Once class handling on a node is complete, the instance listeners are considered.

Hinzufügen von Instanzhandlern, die ausgelöst werden, obwohl Ereignisse als behandelt markiert wurdenAdding Instance Handlers That Are Raised Even When Events Are Marked Handled

Die AddHandler -Methode stellt eine bestimmte Überladung bereit, mit der Sie Handler hinzufügen können, die vom Ereignis System aufgerufen werden, wenn ein Ereignis das Behandlungs Element in der Route erreicht, selbst wenn ein anderer Handler die Ereignisdaten bereits so angepasst hat, dass diese Ereignis als behandelt.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. Dies wird in der Regel nicht ausgeführt.This is not typically done. Ereignishandler können generell geschrieben werden, um alle Bereiche des Anwendungscodes anzupassen, die von einem Ereignis beeinflusst werden können, unabhängig davon, wo es in einer Elementstruktur behandelt wurde, auch wenn mehrere Ergebnisse gewünscht sind.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. Darüber hinaus gibt es in der Regel nur ein Element, das auf dieses Ereignis reagieren muss, und die entsprechende Anwendungslogik ist bereits geschehen.Also, typically there is really only one element that needs to respond to that event, and the appropriate application logic had already happened. Für Ausnahmefälle steht die handledEventsToo-Überladung zur Verfügung, in der ein anderes Element in einer Elementstruktur oder Zusammensetzung von Steuerelementen ein Ereignis bereits als behandelt markiert hat, während andere, in der Elementstruktur höhere oder niedrigere Elemente (je nach Route) ihre eigenen Handler aber aufrufen möchten.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.

Markieren von behandelten Ereignisse als nicht behandeltWhen to Mark Handled Events as Unhandled

Im Allgemeinen sollten Routing Ereignisse, die als behandelt markiert sind, auch durch HandlerHandled , die auf false handledEventsTooreagieren, nicht als nicht behandelt gekennzeichnet werden.Generally, routed events that are marked handled should not be marked unhandled (Handled set back to false) even by handlers that act on handledEventsToo. Allerdings haben einige Ereignisse Ereignisdarstellungen auf hoher und niedriger Ebene, die sich überlappen können, wenn das Ereignis auf höherer Ebene an einer Position in der Struktur und das Ereignis auf niedrigerer Ebene an einer anderen Position angezeigt wird.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. Nehmen Sie beispielsweise TextInput an, dass ein untergeordnetes Element auf ein allgemeines Schlüsselereignis lauscht, z KeyDown. b., während ein übergeordnetes Element auf ein Ereignis auf niedriger Ebene, z. b., lauscht.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. Wenn das übergeordnete Element das Ereignis auf niedrigerer Ebene behandelt, kann das Ereignis auf höherer Ebene sogar im untergeordneten Element unterdrückt werden, das intuitiv als Erstes die Möglichkeit haben sollte, das Ereignis zu behandeln.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.

In diesen Situationen kann es erforderlich sein, für das Ereignis auf niedrigerer Ebene sowohl dem übergeordneten als auch dem untergeordneten Element Handler hinzuzufügen.In these situations it may be necessary to add handlers to both parent elements and child elements for the low-level event. Die Handlerimplementierung für das untergeordnete Element kann das Ereignis auf niedrigerer Ebene als behandelt markieren, aber die Handlerimplementierung des übergeordneten Elements würde dies wieder rückgängig machen, damit andere Elemente weiter oben in der Struktur (und das Ereignis auf höherer Ebene) die Möglichkeit haben, zu reagieren.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. Diese Situation ist aber relativ selten.This situation is should be fairly rare.

Beabsichtigtes Unterdrücken von Eingabeereignissen für die Zusammensetzung von SteuerelementenDeliberately Suppressing Input Events for Control Compositing

Das Hauptszenario, in dem die Klassenbehandlung von Routingereignissen dazu verwendet wird, sind Eingabeereignisse und zusammengesetzte Steuerelemente.The main scenario where class handling of routed events is used is for input events and composited controls. Ein zusammengesetztes Steuerelement besteht per definitionem aus mehreren praktischen Steuerelementen oder Steuerelement-Basisklassen.A composited control is by definition composed of multiple practical controls or control base classes. Häufig möchte der Autor des Steuerelements alle möglichen Eingabeereignisse verbinden, die von den einzelnen Unterkomponenten ausgelöst werden können, um das gesamte Steuerelement als Ereignisquelle zu melden.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. In einigen Fällen möchte der Autor des Steuerelements die Ereignisse von Komponenten möglicherweise vollständig unterdrücken oder ein komponentendefiniertes Ereignis ersetzen, das weitere Informationen enthält oder ein spezifischeres Verhalten impliziert.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. Das kanonische Beispiel, das für jeden Komponenten Autor sofort sichtbar ist, Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) ist, wie ein Button beliebiges Maus Ereignis behandelt, das letztendlich in das intuitive Ereignis aufgelöst wird Click , das alle Schaltflächen aufweisen: ein-Ereignis.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.

Die Button -BasisklasseButtonBase() ist Control abgeleitet, von der wiederum FrameworkElement von UIElementund abgeleitet ist, und ein Großteil der für die Steuerelement Eingabe erforderlichen Ereignis Infrastruktur UIElement ist auf der-Ebene verfügbar.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. Insbesondere UIElement verarbeitet allgemeine Mouse Ereignisse, die Treffer Tests für den Maus Cursor innerhalb seiner Grenzen behandeln, und bietet unterschiedliche Ereignisse für die gängigsten MouseLeftButtonDownSchaltflächen Aktionen, wie z. b.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. UIElementstellt außerdem eine leere virtuelle OnMouseLeftButtonDown als den vorab registrierten Klassen Handler für MouseLeftButtonDownbereit und ButtonBase überschreibt Sie.UIElement also provides an empty virtual OnMouseLeftButtonDown as the preregistered class handler for MouseLeftButtonDown, and ButtonBase overrides it. Ebenso werden ButtonBase von Klassen Handler für MouseLeftButtonUpverwendet.Similarly, ButtonBase uses class handlers for MouseLeftButtonUp. In den über schreibungen, an die die Ereignisdaten weitergegeben werden, markieren die RoutedEventArgs Implementierungen diese Instanz als verarbeitet Handled , trueindem auf festgelegt wird, und dass die gleichen Ereignisdaten entlang der restlichen Route zu anderen Klassen Handlern fortgesetzt werden. auch für Instanzhandler oder Ereignis Setter.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. Außerdem wird das OnMouseLeftButtonUp - Click Ereignis durch die außer Kraft Setzung als nächstes angehoben.Also, the OnMouseLeftButtonUp override will next raise the Click event. Das Endergebnis für die meisten Listener besteht darin, dass MouseLeftButtonDown das MouseLeftButtonUp -Ereignis und das-Ereignis "verschwinden" Clickund stattdessen durch ersetzt werden, einem Ereignis, das mehr Bedeutung hat, da es bekannt ist, dass dieses Ereignis aus einer True-Schaltfläche stammt und nicht aus einigen zusammengesetzter Teil der Schaltfläche oder von einem anderen Element vollständig.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.

Umgehen der Ereignisunterdrückung von SteuerelementenWorking Around Event Suppression by Controls

Manchmal kann dieses Ereignis unterdrückende Verhalten in einzelnen Steuerelementen einige allgemeinere Absichten der Ereignisbehandlungslogik der Anwendung behindern.Sometimes this event suppression behavior within individual controls can interfere with some more general intentions of event handling logic for your application. Wenn beispielsweise die Anwendung aus irgendeinem Grund über einen Handler MouseLeftButtonDown verfügt, der sich im Stamm Element der Anwendung befindet, würden Sie feststellen, dass jeder Maus Klick auf einer Schaltfläche MouseLeftButtonDown keine-oder MouseLeftButtonUp -Handler auf der Stamm Ebene aufruft.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. Das Ereignis selbst würde aufbubblen (wie gesagt, Ereignisroutes werden nicht tatsächlich beendet, das Routingereignissystem ändert nur deren Aufrufverhalten für Ereignishandler, nachdem sie als behandelt markiert wurden).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). Wenn das Routing Ereignis die Schaltfläche erreicht hat ButtonBase , wurde die Klasse MouseLeftButtonDown verarbeitet, die behandelt hat, da Click Sie das Ereignis durch mehr Bedeutung ersetzen wollte.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. Daher würde jeder Standard MouseLeftButtonDown Handler, der die Route weiter oben durchführt, nicht aufgerufen werden.Therefore, any standard MouseLeftButtonDown handler further up the route would not be invoked. Es gibt zwei Verfahren, mit denen Sie sicherzustellen können, dass die Handler unter diesen Umständen aufgerufen werden würden.There are two techniques you can use to ensure that your handlers would be invoked in this circumstance.

Die erste Methode besteht darin, den Handler absichtlich mithilfe der handledEventsToo Signatur von AddHandler(RoutedEvent, Delegate, Boolean)hinzuzufügen.The first technique is to deliberately add the handler using the handledEventsToo signature of AddHandler(RoutedEvent, Delegate, Boolean). Dieses Verfahren zum Anhängen eines Ereignishandlers ist aber nur im Code und nicht in Markup möglich.A limitation of this approach is that this technique for attaching an event handler is only possible from code, not from markup. Die einfache Syntax für die Angabe des Ereignishandlernamens als Ereignisattributwert über Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) ermöglicht dieses Verhalten nicht.The simple syntax of specifying the event handler name as an event attribute value via Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) does not enable that behavior.

Das zweite Verfahren funktioniert nur für Eingabeereignisse, in denen die Tunneling- und Bubblingversionen des Routingereignisses kombiniert werden.The second technique works only for input events, where the tunneling and bubbling versions of the routed event are paired. Für diese Routingereignisse können Sie stattdessen der Vorschau-/Tunnelingversion des Routingereignisses Handler hinzufügen.For these routed events, you can add handlers to the preview/tunneling equivalent routed event instead. Dieses Routingereignis tunnelt ausgehend vom Stamm durch die Route, damit der Code für die Behandlung der Schaltflächenklasse es nicht abfängt, vorausgesetzt, dass Sie den Vorschauhandler in einer Vorgängerebene in der Anwendungsstruktur angefügt haben.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. Wenn Sie diesen Ansatz verwenden, sollten Sie beim Markieren von Vorschauereignissen als behandelt vorsichtig vorgehen.If you use this approach, be cautious about marking any Preview event handled. Wenn Sie das-Ereignis in der Handlerimplementierung als behandelt haben, Handled Click wird das-Ereignis tatsächlich unterdrückt, wenn Sie das-Ereignis in der Handlerimplementierung als gekennzeichnet haben. PreviewMouseLeftButtonDownFor 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. Dies ist in der Regel kein erwünschtes Verhalten.That is typically not desirable behavior.

Siehe auchSee also