Routed events are one of the foundational components of the WPF and Silverlight architecture. If you're not familiar with the concepts behind routed events, check out Brian Noyes'
MSDN Magazine article, Understanding Routed Events and Commands in WPF. This is a great start to understanding the architecture, but Brian doesn't tackle creating your own routed events. After seemingly endless searches, I finally whipped out Reflector to get to the bottom of it. It's pretty simple, but it is different.
For this scenario, I have a collection of items and I needed to raise an event when the selected item changes. Pretty basic. There are three components to this: (1) the routed event identifier, (2) accessor, and (3) event raising call. Again, not too far off what we're used to, but it is slightly different.
public static readonly RoutedEvent SelectedIndexChangedEvent = EventManager.RegisterRoutedEvent("SelectedIndexChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyControl));
public event RoutedEventHandler SelectedIndexChanged
{
add { AddHandler(SelectedIndexChangedEvent, value); }
remove { RemoveHandler(SelectedIndexChangedEvent, value); }
}
This is where I got stuck. I tried the traditional method to raise the event:
protected virtual void OnSelectedIndexChanged(RoutedEventArgs args)
{
if (SelectedIndexChanged != null)
SelectedIndexChanged(this, args);
}
Obviously, we wouldn't be here if this would have worked. Luckily, all we need to do is replace the if block: RaiseEvent(args). I should also mention that, when you initialize the event arguments, you need to specify the routed event it's being triggered for. this is as simple as new RoutedEventArgs(SelectedIndexChangedEvent).
There can (and probably should) be some deeper thinking with respect to the best way to make this call, but I'm not going to cover that here. I have some half-baked ideas about this as well as what hooking up a routed event should look like, but I'll save that for another time.