WPF .NET Core - Routed Events
Written by Mike James   
Thursday, 22 October 2020
Article Index
WPF .NET Core - Routed Events
Adding and removing handlers
Types of Routed Event
Creating your own routed events
Routed events – good or bad



Adding and Removing Handlers

Although you can use AddHandler to add methods to the routed event’s evocation list the system provides alternatives that make a routed event look more like a standard CLR event.

For example, you can write:

button1.Click += new RoutedEventHandler(MyButtonHandler);

The += operator automatically calls the AddHandler method. Notice that you can only use this if the object supports the event and you can’t use it to attach an event to an object that doesn’t implement the event.

For example, you can’t write stackPanel1.Click+= because there is no Click event for a stackPanel. When the += operator can be used, however, you can even drop the creation of a new delegate and write:

button1.Click += MyButtonHandler;

but, of course, MyButtonHandler still has to have the correct signature.

If you want to use anonymous methods you most certainly can, as in:

button2.Click += delegate(object sender,
RoutedEventArgs e)

You can even use the most up-to-date way of creating an anonymous method, the lambda expression:

button2.Click += (object sender, 
RoutedEventArgs e)=>

The result is the same no matter how you code it.

You can also add event handlers within XAML using a syntax very similar to HTML:

<Button  Name="button1" Click="MyButtonHandler">

You can even define an attached event in XAML:

<StackPanel  Name="stackPanel1"
  Button.Click="MyButtonHandler" >

If you want to remove a routed event handler you can simply make use of the RemoveEventHandler method or the overloaded -= operator. Notice that you can only remove an event handler via code – there is no XAML equivalent.

Stop the Bubbling

Suppose you don’t want the event to be handled at a higher level. In this case you can set the Handled property to true. The event arguments are passed to the event handler using RoutedEventArgs object and this is where you will find the Handled property. If you set this to true event bubbling is suppressed.

Change the event handler in our example to read:

void MyButtonHandler(object sender, RoutedEventArgs e)
e.Handled = true;

and when you run the program you will discover that only one messagebox appears per click. Notice that buttons 2 and 3 still respond to the click as they allow their click event to bubble up to the stackFrame level where it is handled and bubbling stopped.

Stopping the bubbling of an event seems like a good idea until you are on the receiving end of a well-meaning control down the hierarchy that has decided that the event you want to handle with some additional behaviour is in fact completely handled.

To help with this problem you can still handle events that have been set to handled.

Sounds confusing and it does have the potential to degenerate into a mess. All you have to do to handle handled events is set the handledEventsToo parameter as true in the AddHandler method.

For example, to force the stackPanel to handle events that are marked as handled you can change its addition to the invocation list to:

new RoutedEventHandler(MyButtonHandler),

Now if you run the program you will discover that the button1  produces two message boxes corresponding to the handling once at the button level and once at the stackPanel level. Notice that there is no XAML equivalent.

How best to make use of these facilities?

I don’t think you should ever mark an event as handled and deprive elements higher in the element tree an opportunity to add behaviour to the event.

The documentation suggests that you should only mark an event as handled if your implementation does something significant or complete and the event needs no further handling. Of course the danger here is that you might think that it’s a significant and complete action but another developer might very well disagree – so use with restraint.





Last Updated ( Thursday, 22 October 2020 )