- Most controls in WPF inherit a series of events from the UIElement class such as PreviewMouseMove (tunneling) and MouseMove (bubbling) events.
- Because these events propagate, however, the events will also tunnel down to the control and then bubble back up the logical tree.
- Tunnelling event first comes to the outermost control, then comes to the inner controls layer by layer. Bubbling event first comes to the innermost control, then comes to outer controls layer by layer.
- For example, if we have a TextBox inside a StackPanel that is inside a Window and we move the mouse around within the TextBox, we’ll see the following events fired:
- PreviewMouseMove on Window
- PreviewMouseMove on StackPanel
- PreviewMouseMove on TextBox (sometimes just stop here)
- MouseMove on TextBox (sometimes won't be fired/triggered)
- MouseMove on StackPanel (sometimes won't be fired/triggered)
- Mousemove on Window (sometimes won't be fired/triggered)
Routed Events
Routed events are events which navigate up or down the visual tree acording to their RoutingStrategy
. The routing strategy can be bubble, tunnel or direct. You can hook up event handlers on the element that raises the event or also on other elements above or below it by using the attached event syntax: Button.Click="Button_Click"
.
Routed events normally appear as pair. The first is a tunneling event called PreviewMouseDown
and the second is the bubbling called MouseDown
. They don't stop routing if the reach an event handler. To stop routing then you have to sete.Handled = true;
- Tunneling The event is raised on the root element and navigates down to the visual tree until it reaches the source element or until the tunneling is stopped by marking the event as handeld. By naming convention it is called
Preview...
and appears before corresponding bubbling event.
- Bubbling The event is raised on the source element and navigates up to the visual tree until it reaches the root element or until the bubbling is stopped by marking the event as handled. The bubbling event is raised after the tunneling event.
- Direct The event is raised on the source element and must be handled on the source element itself. This behavior is the same as normal .NET events.
How to Create a Custom Routed Event
// Register the routed event
public static readonly RoutedEvent SelectedEvent =
EventManager.RegisterRoutedEvent( "Selected", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(MyCustomControl));
// .NET wrapper
public event RoutedEventHandler Selected
{
add { AddHandler(SelectedEvent, value); }
remove { RemoveHandler(SelectedEvent, value); }
}
// Raise the routed event "selected"
RaiseEvent(new RoutedEventArgs(MyCustomControl.SelectedEvent));