Overview of routed events in WPF

WPF introduces an augmentation to the standard .NET event-driven programming model.  A new type of event, called the routed event, allows for much greater flexibility in event-driven programming scenarios.  Subscribing to a routed event can be achieved with the same syntax as a “normal” event (referred to as a CLR event), because it is typical that routed events are exposed via CLR events.

Before discussing routed events any further, it is important to mention the concept of the visual tree.  A WPF user interface is constructed in a layered approach, where one visual element can have zero or more child elements.  The hierarchy of visible layers in a user interface constitutes what is known as its visual tree. 

Routed events are a new infrastructure provided by WPF which allows events to tunnel down the visual tree to the target element, or bubble up to the root element.  When an event is raised, it “travels” up or down the visual tree invoking handlers for that event on any element subscribed to that event it encounters en route.  Note that this tree traversal does not cover the entire visual tree, only the ancestral element chain between the root element and the element which is the target of the event.

Routed event diagram

Figure 1 – Routed events in the visual tree (image borrowed from Routed Events Overview article in the SDK.)

It is common that one logical routed event is represented by two actual events, one tunneling and one bubbling.  The naming convention for tunneling events is PreviewXYZ, where XYZ is the name of the bubbling event.  For example, PreviewMouseLeftButtonDown and MouseLeftButtonDown are a pair of routed events used to notify elements in the visual tree that the user has depressed the left mouse button.  Not all routed events have a tunneling event, and some events do not tunnel or bubble at all.  Those are referred to as direct events, and they are essentially the same as standard CLR events.

The routed notification pattern has many benefits.  One very important benefit of routed events is that a high-level visual element in a UI need not explicitly hook the same event on all of its descendants, such as MouseMove.  Instead it can hook the event on itself, and when the mouse moves over one of its descendants, the high level element will be notified appropriately.

Another important advantage of routed events is that elements at all levels of the visual tree can execute code in response to events of their descendants, without expecting the descendant to notify them when the event fires.   An ancestor element which hooks a tunneling event can even prevent its descendants from ever receiving both the tunneling and bubbling events at all (although it is possible for an element to demand that it is notified of the event, regardless of it is handled or not).

For more information about routed events, including how to create custom routed events, read Routed Events Overview from the SDK.

11 Responses to Overview of routed events in WPF

  1. […] of dependency properties in WPF In my previous blog entry we examined the routed event system used by WPF.  Similar to how routed events augment the […]

  2. marlongrech says:

    good job Josh……

  3. […] in wpf een nieuw event programming model, dat onder andere gebruik maakt van routed events.  Hier staat een beknopt overzicht.Het heeft veel voordelen, maar sommige dingen worden er iets […]

  4. […] One of WPF’s most interesting additions to standard .NET programming has to be routed events.  It took me a while to come up with an accurate way to visualize event routing.  Karl Shifflett […]

  5. […] Routed commands use routed events, as do many other parts of WPF, so it is important to understand them thoroughly.  If you are still hazy on the idea of routed events, check out the blog post I wrote about the topic here. […]

  6. Re: Animation and ShowDialog(…)

    Hi Josh – love your work, nuff said!!!

    I’ve come across an interesting issue concerning routed events and the sequence in how they are handled. The scenario is simple, you create an animation on a button to say scale it up and down when the user clicks on it. In the code behind command handler you create a new window and call ShowDialog on it.

    Now what you see is the dialog opens as expected but the animation only runs when the dialog closes suggesting the code handler gets preference to the animation handler in the Xaml.

    Any suggestions??

    One workaround I did was to handle the animation on a Button.PreviewMouseDown but I wondered if there is a better way.

    Cheers and once again love your articles.

    Andrew

  7. JonS. says:

    So if i want “Immediate Element #1” to fire the routed event then have “Immediate Element #2” handle it, what do I do? They are on the same level in different branches so the default tunneling / bubbling wont work.

    Please don’t tell me i have to use “Root Element” as a pass through for these and manully wire that up.

    This is a common scenario (2 user controls sitting on a window that need to communicate to each other).

  8. Josh Smith says:

    JonS,

    It doesn’t work like that. Routed events only travel between the element tree root and the target element (the one that raised the event). What you’re asking about does not fit into that situation, so you would have to write code to do that.

    I’m not sure why you think that’s such a common scenario. For what you’re talking about, where two usercontrols need to communicate, I’d suggest you do that via a ViewModel. Or, if you don’t want to use the MVVM pattern, you could just hook the necessary events for controls as they’re loaded.

    Josh

  9. JonS. says:

    Thanks for the fast response Josh. We actually plan to use MVVM. We are in the early stages of proof of concepts / development. I guess we just aren’t sure of the correct way to do things.

    Our plan is for everything (every window and user control) to have its own ViewModel. So I guess the logic you are talking about would be in the window’s view model to facilitate communication among the children controls? Does that sound right?

    Your site has been a great resource though. Any other advice you can give us on our first WPF app?

    THANK YOU!

  10. Josh Smith says:

    Jon,

    One thing to consider is that you might also want to create ViewModels for your data model classes, in addition to ViewModels for the Views. This is useful if you display the same data objects in multiple Views, such as a list of Foos in one View and a Foo data entry form in another. You’ll probably want to have the same Foo properties for both Views, so it makes sense to consolidate that into a FooViewModel class that is shared by the ViewModels for the specific Views.

    Josh

  11. […] Josh Smith on Routed Events Posted: Oct 15 2008, 01:51 PM by Nathan Zaugg | with no comments Filed under: WPF, Open Source, .NET Leave a Comment […]