Я хочу быть уверенным, что понял, как распространяются события. Правильно ли приведенное ниже?
Например, давайте рассмотрим, как вызывается событие кнопки Click
при нажатии левой кнопки мыши внутри кнопки.
Кнопка регистрирует событие Click
:
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
создает перенаправленное событие с именемClick
и добавляет его в коллекцию обработчиков событий кнопки с именемEventHandlersStore
. Я считаю, что коллекция (назовем ее_routedEvents
) по типу похожа наDictionary<RoutedEvent, RoutedEventHandler>
. Итак,RegisterRoutedEvent
делает_routedEvents.Add(ClickEvent, null)
.AddHandler
добавляет обработчик кClickEvent
записи вEventHandlersStore
. Если никто не подписался на событиеClick
, обработчик дляClickEvent
остаетсяnull
.
Теперь, когда вызывается RaiseEvent
в OnMouseLeftButtonDown
, вот что происходит и как событие маршрутизируется в соответствии с моим пониманием:
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);
}
Буду признателен, если кто-нибудь сможет меня поправить, если я ошибаюсь, а также расскажет, как вызывается OnMouseLeftButtonDown (я не смог найти его в resharper)