Поделиться через


Общие сведения о присоединенных событиях

Обновлен: Ноябрь 2007

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

В этом разделе содержатся следующие подразделы.

  • Обязательные условия
  • Синтаксис вложенного события
  • Как WPF реализовывает вложенные события
  • Сценарии для вложенных событий
  • Обработка вложенного события в WPF
  • Определение собственных вложенных событий в качестве событий маршрутизации
  • Создание вложенного события WPF
  • Связанные разделы

Обязательные условия

В этом разделе предполагается, что вы прочитали Общие сведения о перенаправленных событиях и Общие сведения о XAML.

Синтаксис вложенного события

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

В синтаксисе XAML вложенное событие определяется не только своим именем события, но и своим собственным типом и именем события, разделенными символом точки (.). Так как имя события квалифицируется с именем его собственного типа, синтаксис вложенных событий позволяет любому присоединенному событию присоединиться к любому элементу, у которого может быть создан экземпляр.

Например, ниже приведен синтаксис XAML для присоединения обработчика для пользовательского вложенного события NeedsCleaning.

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

Обратите внимание на префикс aqua:; префикс в этом случае необходим, поскольку вложенное событие является пользовательским событием, которое поступает из пользовательских сопоставленных xmlns.

Как WPF реализовывает вложенные события

В WPF вложенные события содержатся в поле RoutedEvent и направляются через дерево, после чего они вызываются. Обычно источник вложенного события (объект, который вызывает событие) является системным или служебным источником, а объект, который запускает код, вызывающий событие, напрямую не является частью дерева элементов.

Сценарии для вложенных событий

В WPF вложенные события присутствуют в определенных функциональных областях, где присутствует уровневая абстракция служб, такая как для событий, включенных статическим классом Mouse или классом Validation. Классы, которые используют или взаимодействуют со службой, могут или использовать событие в синтаксисе вложенных событий, или они могут выбрать присоединение к событию в качестве события маршрутизации, которое является частью того, как класс объединяет возможности службы.

Хотя WPF определяет количество вложенных событий, сценариев, в которых вы будете либо использовать, либо непосредственно обрабатывать присоединенное событие, очень мало. Как правило, вложенное событие служит архитектурной цели, но затем передается неприсоединенному (прикреплен с «оболочкой» события CLR) событию маршрутизации.

Например, основное вложенное событие Mouse.MouseDown может намного легче обрабатываться с заданным UIElement с помощью MouseDown на UIElement вместо работы с синтаксисом вложенных событий в XAML или коде. Вложенное событие выполняет свою цель в архитектуре, поскольку оно допускает будущее расширение устройств ввода. Гипотетическим устройствам потребуется только вызвать Mouse.MouseDown, чтобы имитировать ввод данных с мыши, и для этого не нужно будет получать данные из Mouse. Однако этот сценарий включает код обработки событий и обработку XAML вложенного события, не относящегося к этому сценарию.

Обработка вложенного события в WPF

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

В общем случае вложенное событие WPF не очень сильно отличается от события маршрутизации WPF. Различия в том, как событие привязывается и как оно представляется классом в качестве члена (что также влияет на синтаксис обработчика XAML).

Тем не менее, как было отмечено ранее, существующие вложенные события WPF не предназначены непосредственно для обработки в WPF. Более частой целью события является включение составного элемента, чтобы доложить о состоянии родительскому элементу в композиции, в случае которой событие обычно вызывается в коде и также основывается на обработке класса в соответствующем родительском классе. Например, элементы в Selector ожидают вызов вложенного события Selected, которое затем обрабатывается классом с помощью класса Selector и затем, возможно, преобразовывается классом Selector в другое событие маршрутизации, SelectionChanged. Дополнительные сведения о событиях маршрутизации и обработке классов содержатся в разделе Маркировка перенаправленных событий как обработанных и обработка классов.

Определение собственных вложенных событий в качестве событий маршрутизации

Если вы сделаете производный от общих базовых классов WPF, вы сможете реализовать собственные вложенные события, включив определенные методы шаблона в ваш класс и при помощи служебных методов, которые уже присутствуют в базовых классах.

Шаблон выглядит следующим образом.

  • Метод Add*Handler с двумя параметрами. Первый параметр должен определять событие, и у идентифицированного события должны совпадать имена со * в имени метода. Вторым параметром является обработчик для добавления. Метод должен быть открытым и статическим, без возвращаемого значения.

  • Метод Remove*Handler с двумя параметрами. Первый параметр должен определять событие, и у идентифицированного события должны совпадать имена со * в имени метода. Вторым параметром является обработчик для удаления. Метод должен быть открытым и статическим, без возвращаемого значения.

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

Этого общего шаблона еще не достаточно для практической реализации на платформе .NET Framework, так как любая данная реализация чтения XAML может иметь различные схемы для идентификации основных событий в поддерживаемом языке и архитектуре. Это является одной из причин, по которой WPF реализует вложенные события в качестве событий с маршрутизацией; идентификатор, используемый для события (RoutedEvent), уже определен системой событий WPF. К тому же маршрутизация события является расширением естественной реализации в понятиях на уровне языка XAML вложенного события.

Реализация Add*Handler для вложенного события WPF состоит из вызова AddHandler с событием маршрутизации и обработчиком в качестве аргументов.

Эта стратегия реализации и системы событий маршрутизации в целом ограничивает обработку для вложенных событий либо производных классов UIElement, либо производных классов ContentElement, поскольку только эти классы имеют реализации AddHandler.

Например, следующий код определяет вложенное событие NeedsCleaning в собственном классе Aquarium, используя стратегию присоединенных событий WPF объявления присоединенного события в качестве события с маршрутизацией.

<aqua:Aquarium Name="theAquarium" Height="600" Width="800" aqua:AquariumFilter.NeedsCleaning="WashMe"/>

Обратите внимание, что метод, используемый для установления поля идентификатора вложенного события, RegisterRoutedEvent, является фактически тем же методом, используемым для регистрации неприсоединенного события маршрутизации. Вложенные события и события маршрутизации регистрируются в централизованном внутреннем хранилище. Эта реализация хранилища событий позволяет концептуальное рассмотрение «событий в качестве интерфейса», которое описывается в Общие сведения о перенаправленных событиях.

Создание вложенного события WPF

Обычно вам необязательно вызывать существующие вложенные события, определенные WPF, из своего кода. Эти события следуют общей концептуальной модели «службы», и классы служб, такие как InputManager, ответственны за вызов событий.

Однако при определении пользовательского вложенного события на основе модели WPF, основанной на вложенных событиях в RoutedEvent, вы можете использовать RaiseEvent для вызова присоединенного события из любогоUIElement или ContentElement. Вызов события с маршрутизацией (вложенного или нет) требует, чтобы вы объявили конкретный элемент в дереве элементов в качестве источника события; этот источник сообщается в качестве вызывающего RaiseEvent. Определение, какой элемент описывается как источник в дереве, является обязанностью вашей службы

См. также

Основные понятия

Общие сведения о перенаправленных событиях

Терминология синтаксиса XAML

Язык XAML и пользовательские классы