#619 – Event Sequence for the Key Up/Down Events

There are four basic events related to a key being pressed or released that a GUI element can fire in WPF.  An event fires when you press a key down (KeyDown) and a different event fires when you release the key (KeyUp).  When these events fire for an element, they fire first for the element and then work back up the logical tree, firing for each ancestor element.  These are bubbling events.

There are also the PreviewKeyDown and PreviewKeyUp events, which fire before the KeyDown and KeyUp events, but fire from the top of the logical tree down to the control where the event originated.  (Tunneling events).

For a Window containing a StackPanel that contains a TextBox, the event sequence when a user presses a key while the TextBox has focus is:

  • Window_PreviewKeyDown
  • StackPanel_PreviewKeyDown
  • TextBox_PreviewKeyDown
  • TextBox_KeyDown
  • StackPanel_KeyDown
  • Window_KeyDown
  • Window_PreviewKeyUp
  • StackPanel_PreviewKeyUp
  • TextBox_PreviewKeyUp
  • TextBox_KeyUp
  • StackPanel_KeyUp
  • Window_KeyUp

 

#598 – Three Flavors of Routed Events

In WPF, every routed event will adopt one of three different routing strategies:

  • Bubbling – the event propagates up the hierarchy of elements in the user interface
  • Tunneling – the event propagates down the hierarchy of elements
  • Direct – the event fires on the source element, but does not propagate

Routed events that are part of the WPF class libraries will have one of these three routing strategies.  For example:

  • ButtonBase.Click is a bubbling event
  • UIElement.PreviewKeyDown is a tunneling event
  • UIElement.MouseEnter is a direct event

When you define your own routed events, you can also specify one of these routing strategies for the event.

#588 – If You Handle PreviewKeyDown Event, KeyDown Won’t Fire

The PreviewKeyDown and KeyDown events in WPF are paired routed events.  When a user presses a key in a control, the PreviewKeyDown event fires first, as a tunneling event.  When the event has propagated down the logical tree to the control where the key press originated, the KeyDown event fires.  KeyDown propagates up the logical tree, since it is defined as a bubbling event.

If you handle the PreviewKeyDown event as it is propagating down the tree and you mark the event as handled (setting KeyEventArgs.Handled to true), the PreviewKeyDown event will not continue propagating down the tree.

But if you mark PreviewKeyDown as handled, the corresponding KeyDown event will not fire at all.  This works because the two events share the same instance of a KeyEventArgs object, so when PreviewKeyDown marks the event as handled, KeyDown also treats the event as handled.

#587 – The Purpose of Tunneling and Bubbling Events

Many predefined routed events in WPF are available as pairs of events–one tunneling and one bubbling.  The tunneling event typically fires first.  E.g. PreviewKeyDown and KeyDown.

Tunneling events are useful if you want to do some filtering out of different events, for example filtering out disallowed keystrokes.  This might be useful to do in a higher-level parent control, so lower level controls like buttons don’t have to all deal with the invalid input.

 

#586 – Bubbling and Tunneling Events Are Typically Paired

Events defined for preexisting controls in WPF (e.g. a Button) are typically routed events–meaning that the event is propagated up or down the logical tree.  Routed events can either be bubbling events (they propagate up the tree) or tunneling events (they propagate down the tree).

Many events in WPF related to user input are available in pairs, with both a bubbling and a corresponding tunneling event.  For example, the KeyDown event (bubbling) has a corresponding PreviewKeyDown event (tunneling).

When events are paired, the tunneling events will typically fire first, followed by the paired bubbling event.

  1. User presses key
  2. Main Window sees PreviewKeyDown
  3. Outer StackPanel sees PreviewKeyDown
  4. Inner StackPanel sees PreviewKeyDown
  5. TextBox sees PreviewKeyDown
  6. TextBox sees KeyDown
  7. Inner StackPanel sees KeyDown
  8. Outer StackPanel sees KeyDown
  9. Main Window sees KeyDown

#581 – An Example of a Routed Event

In WPF, events that fire as a result of interacting with user interface elements are routed up or down a tree of user interface elements.

In the example below, we’ve attached a handler for the KeyDown event to the first TextBox control.  We also define handlers for the StackPanel that contains this TextBox, as well as the higher level StackPanel and the main Window.

Displaying a message from within each of these event handlers, we see the following output when we move focus to the TextBox and then press a key.

Four events are fired, starting in the TextBox and then preceding up the logical tree.  The event travels up the tree because KeyDown is a bubbling event–it “bubbles up” the logical tree.

In each handler, e.Source refers to control where the event originated and Sender refers to the control that owns the handler.

#580 – Events in WPF are Routed

In Windows Forms, controls make use of traditional .NET events to notify a user that something interesting happened in the control.  When a user clicks on a button, the corresponding Button object will raise a Click event.  You can then define an event handler that does something as a response to the click.

In WPF, events are routed, meaning that the originating control will raise the event but the event will also be passed on to other controls and they will also raise the event.  More specifically, events are passed up (bubbled) or down (tunneled) the logical and visual trees in WPF.

For example, if a StackPanel contains a Button and the user clicks on the button, the Button object will raise a Click event and then the containing StackPanel will also raise a Click event.  The Click event is a bubbling eventso it bubbles up the logical tree.