What's the difference between a class listener and an instance listener in WPF?

2.7k views Asked by At

I am trying to wrap my head around some WPF specific stuff, and have yet to find the concrete relation between the UIElement.AddHandler method and the EventManager.RegisterClassHandler method.

I have googled a bit and found this interesting MSDN article:

http://msdn.microsoft.com/en-us/library/ms747183.aspx

Here it states:

"Routed events consider two different types of listeners to the event: class listeners and instance listeners. Class listeners exist because types have called a particular EventManager API, RegisterClassHandler, in their static constructor, or have overridden a class handler virtual method from an element base class. Instance listeners are particular class instances/elements where one or more handlers have been attached for that routed event by a call to AddHandler."

Alright now so I know the difference between a class and its instance, but somehow I cannot make sense out of this specific part of the document.

Can anyone clear that up for me?

1

There are 1 answers

1
Jarek On BEST ANSWER

I don't know, what exactly do you want to know. Things are pretty simple: you can register handler at instance (object) level, or at class level.

The difference is, when you register event at class level, it will get called first, before any instance level handlers (of course tunneling or bubbling still takes place before, if handling class is lower/higher in logical tree). So you can handle this event at class level and filter whether this event should be handled by instance or not (by setting e.Handled = true you will stop event for going through other handlers). It may be useful in some cases, but for now I have no example in my mind to share.

This sample will register event handler that will be called only when event was raised for specific instance of element:

DockPanel panel = new DockPanel();
panel.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));

And this will create event handler, that will be called each time any DockPanel will get Button.Click event, before instance handler of this DockPanel will get called:

EventManager.RegisterClassHandler(typeof(DockPanel),
    Button.ClickEvent, new RoutedEventHandler(ButtonClass_Click));

If methods were:

private void ButtonClass_Click(object sender, RoutedEventArgs e)
{
    Debug.Write("Class level handler");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    Debug.Write("Instance level handler");
}

This would create output:

Class level handler
Instance level handler

But if in class level handler you would set event args to handeled (e.Handled = true;), it would filter out this event for instance level handler (and bubbling up in logical tree).