Подключенные события WPF против не прикрепленных событий - PullRequest
25 голосов
/ 01 июня 2011

Вопрос в том, что после всех моих исследований я все еще не могу найти разницу между обычным перенаправленным событием и прикрепленным событием. В чем функциональная разница? или другие согласны с тем, что их нет?

Осуществление

Класс ButtonBase объявляет перенаправленное событие с именем ClickEvent; нормальное перенаправленное событие.

public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));

[Category("Behavior")]
public event RoutedEventHandler Click
{
    add
    {
        base.AddHandler(ClickEvent, value);
    }
    remove
    {
        base.RemoveHandler(ClickEvent, value);
    }
}

Класс Mouse объявляет перенаправленное событие MouseDownEvent; прикрепленное событие.

public static readonly RoutedEvent MouseDownEvent = EventManager.RegisterRoutedEvent("MouseDown", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(Mouse));

public static void AddMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
    UIElement.AddHandler(element, MouseDownEvent, handler);
}

public static void RemoveMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
    UIElement.RemoveHandler(element, MouseDownEvent, handler);
}

Оба события регистрируются в EventManager и сохраняются в виде открытых, статических, только для чтения полей одинаковым образом. ClickEvent имеет поле события поддержки CLR с настраиваемыми средствами добавления и удаления, которые вызывают base.AddHandler и base.RemoveHandler соответственно; оба из которых объявлены в базовом классе UIElement, из которого происходит ButtonBase. Вместо этого MouseDownEvent имеет два статических метода AddMouseDownHandler и RemoveMouseDownHandler, которые в конечном итоге вызывают те же два метода AddHandler и RemoveHandler, объявленные в UIElement, как ClickEvent.

Статические методы Add * Handler и Remove * Handler для фактически прикрепленных событий, объявленных в статическом классе, должны следовать определенному соглашению об именах, чтобы система событий WPF могла использовать отражение для поиска подходящих обработчиков добавления и удаления во время выполнения.

<ч />

Использование

Оба события могут иметь обработчики, подключенные в XAML следующим образом:

<Grid Button.Click="Grid_Click"
      Mouse.MouseDown="Grid_MouseDown">
</Grid>

Оба события могут быть прикреплены в коде следующим образом:

// Attach ClickEvent handler.
myGrid.AddHandler(Button.ClickEvent, new RoutedEventHandler(Grid_Click));

// Attach MouseDownEvent handler.
Mouse.AddMouseDownHandler(myGrid, Grid_MouseDown);

Как видите, оба события могут быть прикреплены к элементам, которые не владеют ими или не объявляют их.

<ч />

Заключение - Что такое прикрепленное событие?

Документация MSDN гласит: http://msdn.microsoft.com/en-us/library/bb613550.aspx

расширяемый язык разметки приложений (XAML) определяет языковой компонент и тип события называется прикрепленным событие. Концепция прикрепленного Событие позволяет добавить обработчик для конкретное событие в произвольном элемент, а не к элементу, который на самом деле определяет или наследует событие. В этом случае ни объект, потенциально вызывающий событие ни экземпляр обработки пункта назначения определяет или иным образом «владеет» событием.

Кроме того, официальный учебный комплект MCTS для экзамена 70-511 - Разработка приложений для Windows с использованием Microsoft .NET Framework 4 гласит:

Возможно определить элемент управления обработчик события, которое контроль не может сам подняться. Эти инциденты называются прикрепленными событиями. Например, рассмотрим элементы управления Button в сетке. Класс Button определяет Событие Click, но класс Grid делает не. Тем не менее, вы все еще можете определить обработчик для кнопок в сетке прикрепление события Click Кнопочное управление в коде XAML.

Термин «прикрепленное событие», кажется, расплывчатый во всех учебных ресурсах Microsoft, хотя очевидно, что здесь действуют две разные, но очень тесно связанные концепции: прикрепленные события и синтаксис присоединенных событий XAML. Оба источника Microsoft, которые я цитировал, похоже, ссылаются на синтаксис присоединенных событий XAML, а не на реальные присоединенные события. Однако страница MSDN с обзором прикрепленных событий продолжает показывать вам, как реализовать фактическое присоединенное событие, в отличие от обучающего комплекта.

Mouse.MouseDownEvent - пример перенаправленного события, объявленного в статическом классе с соответствующими статическими обработчиками добавления и удаления, иначе называемыми присоединенным событием. Тем не менее, ButtonBase.ClickEvent является обычным перенаправленным событием, хотя его все еще можно использовать с синтаксисом присоединенного события XAML так же, как и с фактическим вложенным событием.

Целью фактического присоединенного события является то, что оно позволяет разработчикам объявлять новые перенаправленные события для существующих классов, производных от UIElement, без необходимости их подкласса;Это означает, что вы можете просто прикрепить новые перенаправленные события без их фактического существования в классах, которые вы хотите вызвать или обработать.Но, подождите минуту ... разве это не первичная цель чисто перенаправленного события в первую очередь?

Страница обзора перенаправленных событий в состояниях MSDN: http://msdn.microsoft.com/en-us/library/ms742806.aspx

Функциональное определение: маршрутизируемое событие - это тип события, которое может вызывать обработчики для нескольких слушателей в дереве элементов, а не только для объекта, вызвавшего событие.

Из этого функционального определения оноКажется, что любое перенаправленное событие по существу обеспечивает ту же самую функциональность, что и прикрепленное событие.Таким образом, в основном присоединенное событие на самом деле является просто средством объявления перенаправленного события в статическом классе и на самом деле не дает никакой выгоды по сравнению с обычными перенаправленными событиями.

Дайте мне знать, что вы думаете, поскольку я могу что-то упуститьздесь.

Спасибо, Тим Валентин

1 Ответ

4 голосов
/ 24 января 2014

Разница в основном синтаксическая, обе ссылки на делегаты обрабатываются в EventFanager WPF, но то, что дают вложенные события, - это возможность объявлять универсальные функциональные возможности без необходимости раздувать реализацию всех ваших классов.

В случае обычного перенаправленного события класс предоставляет интерфейс, который в какой-то момент может ответить на событие, вызвав обработчик события. Но все, что нужно знать WPF, это то, является ли он объектом производного от заданного типа и зарегистрирован ли обработчик. Это означает, что мы можем создавать более простые иерархии классов, а также поддерживаем принцип Open-Closed (Open to Extension, Closed to Modification). Таким образом, программист может определить новое поведение, которое должно иметь несколько классов, но не нужно изменять исходные классы.

См. Также Прикрепленные свойства

...