В чем разница между слушателем класса и списком экземпляров в WPF?
Я пытаюсь обернуть голову вокруг некоторых вещей, специфичных для WPF, и еще не нашел конкретного отношения между методом UIElement.AddHandler и методом EventManager.RegisterClassHandler.
Я немного погуглил и нашел эту интересную статью на MSDN:
http://msdn.microsoft.com/en-us/library/ms747183.aspx
Здесь говорится:
"В маршрутизируемых событиях учитываются два разных типа слушателей события: слушатели класса и слушатели экземпляра. Слушатели класса существуют, потому что типы вызвали конкретный API-интерфейс EventManager, RegisterClassHandler, в своем статическом конструкторе или переопределили виртуальный метод обработчика класса из элементной базы прослушиватели экземпляров - это особые экземпляры / элементы класса, в которых один или несколько обработчиков были присоединены для этого перенаправленного события путем вызова AddHandler. "
Хорошо, теперь я знаю разницу между классом и его экземпляром, но каким-то образом я не могу разобраться в этой конкретной части документа.
Может кто-нибудь прояснить это для меня?
1 ответ
Я не знаю, что именно ты хочешь знать. Все довольно просто: вы можете зарегистрировать обработчик на уровне экземпляра (объекта) или на уровне класса.
Разница в том, что когда вы регистрируете событие на уровне класса, оно будет вызываться первым, прежде чем будут обработаны какие-либо экземпляры уровня экземпляра (конечно, туннелирование или образование пузырьков по-прежнему имеют место раньше, если класс обработки ниже / выше в логическом дереве). Таким образом, вы можете обработать это событие на уровне класса и отфильтровать, должно ли это событие обрабатываться экземпляром или нет (путем установки 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;
), это отфильтровывает это событие для обработчика уровня экземпляра (и всплывает в логическом дереве).