В чем разница между слушателем класса и слушателем экземпляра в WPF? - PullRequest
8 голосов
/ 05 февраля 2011

Я пытаюсь обернуть голову вокруг некоторых вещей, специфичных для WPF, и до сих пор не нашел конкретного отношения между методом UIElement.AddHandler и методом EventManager.RegisterClassHandler.

Я немного погуглил и нашел эту интересную статью MSDN:

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

Здесь говорится:

"Маршрутизируемые события относятся к двум различным типампрослушивателей события: прослушиватели классов и прослушиватели экземпляров. Прослушиватели классов существуют, потому что типы вызывали определенный API EventManager, RegisterClassHandler, в своем статическом конструкторе или переопределяли виртуальный метод обработчика класса из базового класса элемента.экземпляры / элементы, в которых один или несколько обработчиков были присоединены для этого перенаправленного события с помощью вызова AddHandler. "

Хорошо, теперь я знаю разницу между классом и его экземпляром, но каким-то образом я не могу понять изэта конкретная часть документа.

Может кто-нибудь прояснить это для меня?

1 Ответ

11 голосов
/ 05 февраля 2011

Я не знаю, что именно вы хотите знать. Все довольно просто: вы можете зарегистрировать обработчик на уровне экземпляра (объекта) или на уровне класса.

Разница в том, что когда вы регистрируете событие на уровне класса, оно будет вызываться первым, до того, как будут обработаны какие-либо экземпляры уровня (конечно, туннелирование или образование пузырьков по-прежнему имеют место раньше, если класс обработки ниже / выше в логическом дереве). Таким образом, вы можете обработать это событие на уровне класса и отфильтровать, должно ли это событие обрабатываться экземпляром или нет (установив e.Handled = true, вы остановите событие для прохождения через другие обработчики). В некоторых случаях это может быть полезно, но пока я не могу поделиться своим примером.

В этом примере будет зарегистрирован обработчик события, который будет вызываться только при возникновении события для определенного экземпляра элемента:

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

И это создаст обработчик события, который будет вызываться каждый раз, когда любой DockPanel получит событие Button.Click, прежде чем будет вызван обработчик экземпляра этого DockPanel:

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

Если бы методы были:

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");
}

Это создаст вывод:

Обработчик уровня класса
Обработчик уровня экземпляра

Но если в обработчике уровня класса вы установите для аргументов события значение handeled (e.Handled = true;), это отфильтрует это событие для обработчика уровня экземпляра (и всплывет в логическом дереве).

...