|Tuesday, 16 November 2010|
Page 3 of 5
Types of routed event
So far we have only considered routed events that “bubble” up the element hierarchy but there are three distinct types of routed event:
The type of routing an event uses is all a matter of how it is registered. You can’t change the way an event is routed and so there are essentially three predefined classes.
You can usually tell that an event is tunnelling because its name starts with “preview” and a tunnelling event often comes paired with a bubbling event. However there is no such obvious way to discover if an event is bubbling or direct. If you are really stuck, or need to determine the type of an event at runtime, it is worth knowing that you can use the RoutingStrategy property as in:
together with the RoutingStrategy static enumeration to find out exactly how an event will be routed.
As you might guess from the use of the standard naming convention for tunnelling events – i.e. Previeweventname – they are a way of allowing components to take a sneak look at what is happening before allowing lower level components to process the event. To achieve the same result without tunnelling events you need to use techniques that let you take a peak at an input stream, or whatever, before allowing the usual object that processes the stream to work with it. This all makes better sense after a simple example.
Place a textbox on the form and add the following event handlers:
The event handler simply displays the element that invoked it:
void MyKeyHandler(object sender,
If you now run the program, select the textbox, and press a key you will first see that the Window1 event handler responds and then the textbox’s event handler. The Window1 event handler could examine the key code by changing from RoutedEventArgs to KeyEventArgs and from RoutedEventHandler to KeyEventHandler:
void MyKeyHandler(object sender, KeyEventArgs e)
The RoutedEventArgs is the base class for more specialised object that carry additional information about the routed event.
As well as the PreviewKeyDownEvent which tunnels there is also the KeyDownEvent which bubbles. Given they are both triggered by the same external event you can make use of them both and at the same time if you want to.
The key idea here is that the tunnelling event always gets priority and then the bubbling event is routed. For example, if you change the event handlers to:
and run the program again you will see first the event handler invoked on Window1, then Textbox1, then Textbox1 again and finally Window1.
You can see that this is very sophisticated but it is also potentially overly complex and could be dangerous. The order of invocation of the event handlers is well defined but any of them can set the Handled property to true which stops event routing both in the tunnelling and bubbling directions.
The reason that this works is that events use the same KeyEventArgs object within the event handler invocations. Once again you can also add event handlers so that they ignore the Handled property and execute in spite of an attempt to stop them.
Given an element hierarchy of reasonable depth this is a recipe for complexity!
|Last Updated ( Tuesday, 16 November 2010 )|