Обработка событий в Visual Basic и WPF

Специально для языка Visual Basic .NET для того, чтобы связывать обработчики событий с экземплярами вместо присоединения обработчиков событий с атрибутами или использования метода AddHandler, предусмотрено ключевое слово Handles. Однако метод присоединения обработчиков к экземплярам Handles имеет некоторые ограничения, так как синтаксис Handles не поддерживает некоторые возможности перенаправленных событий системы событий WPF.

Использование ключевого слова Handles в приложениях WPF

Все обработчики событий, которые подключены к экземплярам и событиям с помощью Handles, должны быть определены внутри объявления частичного класса экземпляра, который также является требованием для обработчиков событий, назначенных с помощью значений атрибутов в элементах. Можно указать только Handles для элемента на странице, который имеет значение свойства Name (или объявлена x:Name Directive). Это происходит потому, что свойство Name в XAML создает ссылку на экземпляр, необходимую для поддержки формата ссылки Instance.Event, который требуется синтаксисом Handles. Единственный элемент, который можно использовать для Handles без ссылки на Name, является экземпляром корневого элемента, который определяет разделяемый класс.

Можно назначить один и тот же обработчик для нескольких элементов, разделяя запятыми ссылки Instance.Event после Handles.

Можно использовать Handles для назначения более одного обработчика для той же ссылки Instance.Event. Не следует придавать значения порядку, в котором приведены обработчики в ссылке Handles; предполагается, что обработчики, обрабатывающие одно и тоже событие, могут вызываться в любом порядке.

Чтобы удалить обработчик, который был добавлен с Handles в объявлении, можно вызвать RemoveHandler.

Можно использовать Handles для присоединения обработчиков для перенаправленных событий до тех пор, пока обработчики присоединяются к экземплярам, которые определяют обрабатываемое в таблицах элементов событие. Обработчики для перенаправленных событий, присоединенные с помощью Handles, следуют тем же правилам маршрутизации, что и обработчики, присоединенные как атрибуты XAML, или с общей сигнатурой AddHandler. Это означает, что если событие уже помечено как обрабатываемое (свойству Handled в данных события присвоено значение True), то обработчики, присоединенные с помощью Handles, не вызываются в ответ на этот экземпляр события. Событие не может быть помечено как обрабатываемое обработчиками экземпляров из другого элемента маршрута или обработкой класса либо из текущего элемента, либо из более ранних элементов маршрута. Для событий ввода, которые поддерживают события восходящей и нисходящей маршрутизации, нисходящая маршрутизация может пометить пару событий как обрабатываемую. Дополнительные сведения о перенаправленных событиях см. в разделе Общие сведения о перенаправленных событиях.

Ограничения ключевого слова Handles при добавлении обработчиков

Ключевое слово Handles не может ссылаться на обработчики для присоединенных событий. Необходимо использовать метод доступа add для присоединенных событий или атрибуты события typename.eventname в XAML. Дополнительные сведения см. в разделе Общие сведения о перенаправленных событиях.

Для перенаправленных событий можно использовать Handles только для назначения обработчиков экземплярам, в которых это событие существует в таблице элементов экземпляра. Однако в общем случае маршрутизации событий, родительский элемент может быть слушателем события от дочерних элементов, даже если этого события нет в таблице элементов родительского элемента. В синтаксисе атрибута это можно указать через форму атрибута typename.membername, которая определяет, какой тип фактически определяет обрабатываемое событие. Например, родительская Page (без определенного события Click) может прослушивать события нажатий кнопки путем назначения атрибута обработчика в форме Button.Click. Но Handles не поддерживает форму typename.membername, так как он должен поддерживать конфликтующую форму Instance.Event. Дополнительные сведения см. в разделе Общие сведения о перенаправленных событиях.

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

Примечание.

Не используйте синтаксис Handles в коде Visual Basic, если требуется задать обработчик событий для того же события в XAML. В таком случае обработчик событий вызывается дважды.

Как в WPF реализуются функциональные возможности ключевого слова Handles

После компиляции страницы XAML промежуточный файл объявляет ссылки FriendWithEvents на каждый элемент страницы, для которого задано свойство Name (или объявлена x:Name Directive). Каждый именованный экземпляр является потенциальным элементом, который можно присвоить обработчику с помощью Handles.

Примечание.

В Visual Studio IntelliSense может показать варианты завершения элементами, доступными для ссылки Handles на странице. Но для того чтобы промежуточный файл смог заполнить все ссылки Friends, может потребоваться один проход компиляции.

См. также