Preview Events

Preview events, also known as tunneling events, are routed events where the direction of the route travels from the application root towards the element that raised the event and is reported as the source in event data. Not all event scenarios support or require preview events; this topic describes the situations where preview events exist, how applications or components should handle them, and where creating preview events in custom components or classes might be appropriate.

Preview Events and Input

When you handle Preview events in general, be cautious about marking the events handled in the arguments. Handling a Preview event on any element other than the element that raised it has the effect of not allowing an element to handle its own event.

For input events specifically, Preview events also share event arguments instances with the equivalent bubbling event. This means that if you use a Preview event class handler to mark the input event handled, the bubbling input event class handler will not be invoked. Or, if you use a Preview event instance handler to mark the event handled, a general-purpose handler for the bubbling event will not be invoked. Class handlers or instance handlers can register themselves with an option to be invoked even if the event is marked handled, but that technique is not commonly used.

For more information about class handling and how it relates to Preview events see Marking Routed Events as Handled, and Class Handling.

Working Around Event Suppression by Controls

One scenario where Preview events are used is for input events and controls. Sometimes, the author of the control suppresses a certain event from originating from their control, perhaps in order to substitute a component-defined event that carries more information or implies a more specific behavior. For instance, a Windows Presentation Foundation (WPF) Button suppresses normal MouseLeftButtonDown bubbling events raised by the Button or its composite elements in favor of raising a Click event that is always raised by the Button itself. If other elements towards the root of your application still wanted an opportunity to handle a suppressed event, one alternative is to attach handlers in code with handledEventsToo specified as true. But often a simpler technique is to change the routing direction you handle to be the Preview equivalent of an input event. For instance, if a suppresses MouseLeftButtonDown, try attaching a handler for PreviewMouseLeftButtonDown instead. This technique only works for input events such as MouseLeftButtonDown, that use tunnel/bubble pairs, raise both events, and share the event data.

See Also