I want to be sure that I understood how the events are propagated. Is the below correct?
For example, let's examine how button's Click
event is invoked when mouse left button is clicked within the button.
The button registers the Click
event:
public class Button : ButtonBase
{
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Button));
public event RoutedEventHandler Click
{
add { AddHandler(ClickEvent, value); }
remove { RemoveHandler(ClickEvent, value); }
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
...
RaiseEvent(new RoutedEventArgs(ClickEvent, this));
...
}
...
}
EventManager.RegisterRoutedEvent
creates routed event namedClick
and adds it to button's event handlers collection calledEventHandlersStore
. I believe the collection(let's call it_routedEvents
) is of type similar toDictionary<RoutedEvent, RoutedEventHandler>
. So,RegisterRoutedEvent
does_routedEvents.Add(ClickEvent, null)
.AddHandler
adds handler toClickEvent
entry inEventHandlersStore
. If no one has subscribed toClick
event the handler forClickEvent
remainsnull
.
Now, when RaiseEvent
is invoked, in OnMouseLeftButtonDown
, this is what happening and how the event is routed according to my understanding:
void RaiseEvent(RoutedEventArgs e)
{
DependencyObject current = this;
do
{
// check if the element has handler for routed event
var handler = current.GetHandlerFromEventHandlersStore(e.RoutedEvent);
if (handler != null)
{
handler(e);
}
// the event was NOT handled -> route the event to the parent
// OR
// the event was handled but wasn't marked as handled -> route the event further to parent
if (e.Handled == false)
{
// assuming that RoutingStrategy is Bubble
current = VisualTreeHelper.GetParent(current);
}
// continue until either it has been handled or it reaches the root element
} while (e.Handled == false && current != null);
}
I'll appreciate if someone could correct me if I'm wrong and also tell me how OnMouseLeftButtonDown is called (I couldn't find it in resharper)