Consuming Routed Events in WPF

In my last post I gave a brief explanation of what a RoutedEvent is all about.  In this blog post I am going to show you how to consume a custom RoutedEvent.

Let’s start off by defining a simple event (in a vanilla WPF Application using the default WPF Application project template in VS2010).

This is covered in more detail in my previous post, yet just to re-summarize:

  1. Declare the static RoutedEvent as a field in your class
  2. Register the RoutedEvent in a static constructor
  3. Raise the event… somewhere

With all that done, we can run the application and see what happens, we are interested in the console output at this point, rather than the app itself (it’s not too fancy anyway!), though if you are following along, clicking a bit on the Window so as to raise the event.

As we can see, the output is as expected.

  1. First the RoutedEvent was registered (in the static constructor)
  2. The Window was initialized (in the instance constructor)
  3. We clicked on the window… and the event was raised (in the overridden OnMouseLeftButtonDown method)

Next up, we may want to actually do something when this event happens, so we make a call to UIElement’s AddHandler method, and register a delegate of type RoutedEventHandler.

Firing it all up now and clicking, produces the following output

Which as expected is invoking our event handler.  But what if we want to register the event handler in our XAML? There is currently nothing public about our event, we therefore have to wrap our event in a standard .NET event handler, and this way expose it to XAML (after importing the namespace).

And following this, we can import the namespace, and register an event handler accordingly (we’ll use the same event handler as before).

Running and clicking on the window, now produces the following:

As you can see, the only real difference is that during the initialization phase, our XAML defined handler was also registered using out event wrapper.

That’s all there is to it.  I hope someone finds this helpful