Dot Net For All

Bubbling, Tunneling and Direct routed events

Events in WPF Introduction

In this article I will discuss about the event types in WPF. The type of events in WPF are Bubbling event, tunneling event which are routing events and direct event. I will also describe each of these events with example of each.

As we know that most of the controls in WPF are content controls and a content control can hold any other control element. Due to this scenario of holding child controls in the parent control WPF has been evolved to handle the events in various ways. Controls in WPF basically can be interacted with the help of routed events.

What is Routed Events?

Practically speaking about the routed events we can say that – The routed events are type of events that can invoke handlers on multiple listeners on an visual tree , rather then just on object that raised the event.

The implementation definition for the routed events can be – A CLR event that is backed by instance of the RoutedEvent class and is processed by the event system in WPF.

Why Routed Event?

As in the beginning of this article I have told that controls in WPF can contain other controls with the help of templates which I have discussed here In this case it is very much possible that we should not be ignoring the events raised by the inner control or the template control.

As as example suppose we have button without any template for it, this is a simple case in which the events raised on the button control can be handled by the buttons handlers.

But we have another case in which we have an image present as the control template of the button as shown in the figure below

In this we do not want to miss any of the events which take place also with the image. In that case the simple routing strategy will not be helpful. Here we have to use the bubbling event of the WPF which will be handled at the button.

Going further I will discuss all the routing strategies present in the WPF event system. Below are the three routing strategies in WPF.

  1. Direct events – These are the events that are raised by a control and handled by that source control itself. These events are not at all traversed up or down the visual tree unlike other two types of events.
  2. Bubbling events – Events handlers in the source controls are handled by the handlers in the source control which successively is handled by the parent element and following the same strategy it travels up the visual tree until it reaches the element tree root.
  3. Tunneling events – Events handlers at the element tree root element are invoked first and traverses down the visual element tree until it reaches the event element source i.e the control at which the event originally occurred. These events start with the prefix Preview.

Bubble and Tunnel event Demo

In this part of the article I will demo how the tunnel and bubble event work. In the sequence of the events Tunnel events are the one which are raised first and then bubble event start taking place as shown in the below figure.

In the above XAML I have image inside a button. When the user clicks on the image, first the tunnel image is traversed from Window down to Image and these can handled in the PreviewMouseDown event of each control.

And after the event is handled at the image it is again traversed back in form of bubble event up to the MainWindow.

Window > Grid > Button > Image (Tunnel Event)

Image >Button > Grid > Window (Bubble Event)

In the code below I will show you how I have taken care of each and every event handler for the controls and logging the occurrence of the events in a list box.

 private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            Message.Add("\n Event handled at window");
        }

        private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            Message.Add("\n Event handled at grid");            
        }

        private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            Message.Add("\n Event handled at button");                
        }

        private void Image_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Message.Add("\n Event handled at image");            
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Message.Add("\n Event handled at button for bubble");
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(sb.ToString()); 
        }

        private void Grid_Click_1(object sender, RoutedEventArgs e)
        {
            Message.Add("\n Event handled at grid for bubble");
        }

Now when I click on the Image in the Button I will get the event log as shown below figure.

From the above log on the right hand side we can see that the click event on image is handled first at the window, grid, button and at the image in the last and goes upward in the same order.

if we want to prevent the event from being traversed at any of these events we have to set e.Handled = true at the handler as shown below code snippet. The event is handled at the window itself

private void Window_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            Message.Add("\n Event handled at window");
            e.Handled = true;
        }

The code for this application is attached here for your referenceIn this article I have covered the concept of routed events in WPF and their usage.

Top career enhancing courses you can't miss

My Learning Resource

Excel your system design interview