Trace (route) that call!

Have you ever used EventManager.RegisterClassHandler()? If so, make sure you know what you’re doing. This method allows you to listen to events passing through (as I like to put it) an element (i.e. bubbling or tunneling), regardless of the class that invoked the call. Most of the times you would call it in a static constructor, and pass it a typeof of that class, but that is only a recommendation. The documentation is a bit weak on this point.

This can be a very powerful tool if you use it right. Let me demonstrate. Say you want to listen to all button clicks in your app. Normally you would put this in your main Window (by calling the above method or UIElement.AddHandler() instance method) so all the ButtonBase.Click event would bubble up to the Window and get caught.

But what you can actually do is call the RegisterClassHandler from anywhere you like (it doesn’t have to be a static constructor or even a DependencyObject. But remember that every call would add a handler, so beware of multiple registrations!):

EventManager.RegisterClassHandler(typeof(ButtonBase), ButtonBase.ClickEvent, new RoutedEventHandler(SomeMethod), true);

This method has no idea from where it’s called, nor does it care. All that matters is that the bubbling or tunneling passes through an element of the type you specified.

Since the Click event would always pass through a ButtonBase (well, actually originate from one. That is, unless you invoke it from some custom class, which doesn’t make too much sense most of the time. But I’m going off on a tangent here.) the method would be invoke for every button click. The last parameter makes sure it’s invoked even if you marked the event as handled somewhere along the way (albeit redundant in this case, since we handle it right at the root of the bubble.)