Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Основные API
Мы описываем концепцию программирования событий в приложении среды выполнения Windows при использовании XAML для определения пользовательского интерфейса. Обработчики событий можно назначать как часть объявлений для элементов пользовательского интерфейса в XAML или добавлять обработчики в код. Среда выполнения Windows поддерживает перенаправленные события: некоторые входные события и события данных могут обрабатываться объектами за пределами объекта, который вызвал событие. Маршрутные события полезны при определении шаблонов элементов управления или при использовании страниц и контейнеров макета.
События в качестве концепции программирования
Как правило, понятия событий при программировании приложения среды выполнения Windows похожи на модель событий на самых популярных языках программирования. Если вы уже знаете, как работать с событиями Microsoft .NET или C++, у вас есть преимущество. Но вам не нужно знать так много о концепциях модели событий, чтобы выполнять некоторые основные задачи, такие как подключение обработчиков.
При создании приложения WinUI (или UWP) пользовательский интерфейс определяется в разметке (XAML). В синтаксисе разметки XAML некоторые принципы подключения событий между элементами разметки и сущностями кода среды выполнения аналогичны другим веб-технологиям, таким как ASP.NET или HTML5.
Замечание
Код, который обеспечивает логику выполнения для пользовательского интерфейса, определяемого в XAML, часто называется код-за или файлом программной части. В представлениях решения Microsoft Visual Studio эта связь отображается графически, причем файл программной части зависит от страницы XAML и вложен в неё.
Button.Click: введение в работу с событиями и XAML
Одной из наиболее распространенных задач программирования для приложения среды выполнения Windows является запись входных данных пользователя в пользовательский интерфейс. Например, в пользовательском интерфейсе может быть кнопка, которую пользователь должен нажать, чтобы отправить сведения или изменить состояние.
Вы определяете пользовательский интерфейс для приложения среды выполнения Windows путем создания XAML. Обычно XAML является результатом работы области проектирования в Visual Studio. Вы также можете написать XAML в редакторе обычного текста или стороннем редакторе XAML. Создавая этот XAML, можно связывать обработчики событий для отдельных элементов пользовательского интерфейса одновременно с определением всех остальных атрибутов XAML, устанавливающих значения свойств этого элемента пользовательского интерфейса.
Чтобы привязать события в XAML, укажите строковое имя метода обработчика, который вы уже определили или определите позже в вашем коде-behind. Например, этот XAML определяет объект Button с другими свойствами (атрибут x:Name, Content), которые назначены как атрибуты, и связывает обработчик для события Click кнопки, ссылаясь на метод с именем ShowUpdatesButton_Click
:
<Button x:Name="showUpdatesButton"
Content="{Binding ShowUpdatesText}"
Click="ShowUpdatesButton_Click"/>
Подсказка
Проводка событий — это термин программирования. Речь идет о процессе или коде, указывающем, что возникновения события должны вызывать метод именованного обработчика. В большинстве процедурных моделей кода проводка событий является неявным или явным кодом AddHandler, который называет как событие, так и метод, и обычно включает в себя целевой экземпляр объекта. В XAML функция AddHandler неявна, а проводка событий полностью состоит из именования события в качестве имени атрибута элемента объекта и именования обработчика в качестве значения этого атрибута.
Вы пишете фактический обработчик на языке программирования, который вы используете для всего кода приложения и его реализованного кода. С помощью атрибута Click="ShowUpdatesButton_Click"
, вы создали контракт, который позволяет при компиляции разметки XAML в рамках действия сборки вашей интегрированной среды разработки, а также при дальнейшем синтаксическом анализе XAML во время загрузки приложения, находить метод с именем ShowUpdatesButton_Click
как часть кода приложения.
ShowUpdatesButton_Click
должен быть методом, реализующим совместимую сигнатуру метода (на основе делегата) для любого обработчика события Click . Например, этот код определяет ShowUpdatesButton_Click
обработчик.
private void ShowUpdatesButton_Click (object sender, RoutedEventArgs e)
{
Button b = sender as Button;
//more logic to do here...
}
Private Sub ShowUpdatesButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim b As Button = CType(sender, Button)
' more logic to do here...
End Sub
void winrt::MyNamespace::implementation::BlankPage::ShowUpdatesButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e)
{
auto b{ sender.as<Windows::UI::Xaml::Controls::Button>() };
// More logic to do here.
}
void MyNamespace::BlankPage::ShowUpdatesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
Button^ b = (Button^) sender;
//more logic to do here...
}
В этом примере метод ShowUpdatesButton_Click
основан на делегате RoutedEventHandler. Вы поймёте, что это делегат, который следует использовать, так как увидите, что этот делегат указан в синтаксисе метода Click.
Подсказка
Visual Studio предоставляет удобный способ назвать обработчик событий и определить метод обработчика при редактировании XAML. При указании имени атрибута события в текстовом редакторе XAML подождите минуту, пока не отобразится список Microsoft IntelliSense. Если щелкнуть <новый обработчик> событий из списка, Microsoft Visual Studio предложит имя метода на основе x:Name элемента (или имени типа), имени события и числового суффикса. Затем щелкните правой кнопкой мыши имя выбранного обработчика событий и щелкните "Перейти к обработчику событий". Эта операция приведет непосредственно к добавленному определению обработчика событий, как это показано в редакторе кода вашего файла программной части для XAML-страницы. Обработчик событий уже имеет правильную подпись, включая параметр отправителя и класс данных событий, который использует событие. Кроме того, если метод обработчика с правильной сигнатурой уже существует в коде, имя этого метода отображается в раскрывающемся списке автоматического завершения вместе с параметром <Новый обработчик событий>. Вы также можете нажать клавишу TAB в качестве сочетания клавиш вместо того чтобы щелкать элементы списка IntelliSense.
Определение обработчика событий
Для объектов, которые являются элементами пользовательского интерфейса и объявленными в XAML, код обработчика событий определяется в частичном классе, который служит кодом для страницы XAML. Обработчики событий — это методы, которые записываются в составе частичного класса, связанного с XAML. These event handlers are based on the delegates that a particular event uses. ru-RU: Эти обработчики событий основаны на делегатах, которые использует конкретное событие. Методы обработчика событий могут быть общедоступными или частными. Приватный доступ работает, поскольку обработчик и экземпляр, созданные XAML, в конечном итоге объединяются с генерацией кода. Как правило, рекомендуется сделать методы обработчика событий закрытыми в классе.
Замечание
Обработчики событий для C++ не определяются в частичных классах, они объявляются в заголовке как член частного класса. Действия сборки для проекта C++ заботятся о создании кода, который поддерживает систему типов XAML и модель программной части для C++.
Параметр отправителя и данные события
Обработчик, который вы пишете для события, может получить доступ к двум значениям, доступным в качестве входных данных для каждого случая, когда вызывается обработчик. Первым таким значением является отправитель, который является ссылкой на объект, в котором подключен обработчик. Параметр отправителя вводится в качестве базового типа объекта . Распространенный способ — приведение отправителя к более точному типу. Этот метод полезен, если вы ожидаете проверить или изменить состояние самого объекта отправителя . На основе собственного дизайна приложения вы обычно знаете, как безопасно привести отправителя к типу, в зависимости от того, где прикреплен обработчик или других особенностей проектирования.
Второе значение — это данные событий, которые обычно отображаются в определениях синтаксиса как параметр e (или args). Вы можете узнать, какие свойства для данных событий доступны, просмотрев параметр e делегата, назначенный для конкретного события, которое вы обрабатываете, а затем с помощью IntelliSense или обозревателя объектов в Visual Studio. Вы также можете использовать справочную документацию по среде выполнения Windows.
Для некоторых событий значения конкретных свойств данных события настолько же важны, как и знание о том, что событие произошло. Это особенно верно для входных событий. Для событий указателя положение указателя при возникновении события может быть важным. Для событий клавиатуры нажатия всех возможных клавиш запускают события KeyDown и KeyUp. Чтобы определить, какой ключ нажимается пользователем, необходимо получить доступ к keyRoutedEventArgs , который доступен обработчику событий. Дополнительные сведения об обработке событий ввода см. в разделе "Взаимодействие с клавиатурой " и ввод указателя указателя. События ввода и сценарии ввода часто имеют дополнительные аспекты, которые не рассматриваются в этом разделе, например захват указателя для событий указателя, а также клавиши-модификаторы и коды клавиш платформы для событий клавиатуры.
Обработчики событий, использующие асинхронный шаблон
В некоторых случаях вы хотите использовать API, использующие асинхронный шаблон в обработчике событий. Например, можно использовать кнопку на панели приложений для отображения средства выбора файлов и взаимодействия с ним. Однако многие API средства выбора файлов являются асинхронными. Они должны вызываться в рамках асинхронного/ожидающего контекста, и компилятор будет это обеспечивать. Что можно сделать, так это добавить ключевое слово async в обработчик событий, чтобы теперь он был asyncvoid. Теперь обработчик событий может выполнять асинхронные или ожидаемые вызовы.
Добавление обработчиков событий в код
XAML — это не единственный способ назначить обработчику событий объекту. Чтобы добавить обработчики событий в любой заданный объект в коде, включая объекты, которые недоступны для использования в XAML, можно использовать синтаксис, характерный для языка, для добавления обработчиков событий.
В языке C# синтаксис заключается в использовании оператора +=
. Вы регистрируете обработчик, указывая имя метода обработчика событий на правой стороне оператора.
Если вы используете код для добавления обработчиков событий в объекты, отображаемые в пользовательском интерфейсе во время выполнения, рекомендуется добавить такие обработчики в ответ на событие времени существования объекта или обратный вызов, например Loaded или OnApplyTemplate, чтобы обработчики событий соответствующего объекта были готовы к событиям, инициированным пользователем во время выполнения. В этом примере показана структура XAML структуры страницы, а затем предоставляется синтаксис языка C# для добавления обработчика событий в объект.
<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded">
<StackPanel>
<TextBlock Name="textBlock1">Put the pointer over this text</TextBlock>
...
</StackPanel>
</Grid>
void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
textBlock1.PointerEntered += textBlock1_PointerEntered;
textBlock1.PointerExited += textBlock1_PointerExited;
}
Замечание
Существует более подробный синтаксис. В 2005 году в C# была добавлена функция, называемая вывод делегата, которая позволяет компилятору выводить новый экземпляр делегата и использовать предыдущий, более простой синтаксис. Подробный синтаксис функционально идентичен предыдущему примеру, но явно создает новый экземпляр делегата перед его регистрацией, поэтому не использует преимущества вывода типов делегатов. Этот явный синтаксис менее распространен, но его можно увидеть в некоторых примерах кода.
void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
textBlock1.PointerEntered += new PointerEventHandler(textBlock1_PointerEntered);
textBlock1.PointerExited += new MouseEventHandler(textBlock1_PointerExited);
}
Существует два варианта синтаксиса Visual Basic. Одним из них является параллелизм синтаксиса C# и подключение обработчиков непосредственно к экземплярам. Для этого требуется ключевое слово AddHandler , а также оператор AddressOf , который разыменовывает имя метода обработчика.
Другой вариант синтаксиса Visual Basic — использовать ключевое слово Handles для обработчиков событий. Этот метод подходит для случаев, когда обработчики, как ожидается, существуют на объектах во время загрузки и сохраняются в течение всего времени существования объекта. Использование дескрипторов для объекта, определенного в XAML, требует предоставления имени / x:Name. Это имя становится квалификатором экземпляра, необходимым для части Instance.Event синтаксиса Handles . В этом случае вам не требуется обработчик событий, основанный на времени жизни объекта, чтобы инициировать присоединение других обработчиков событий; соединения Handles создаются при компиляции страницы XAML.
Private Sub textBlock1_PointerEntered(ByVal sender As Object, ByVal e As PointerRoutedEventArgs) Handles textBlock1.PointerEntered
' ...
End Sub
Замечание
Visual Studio и его область конструктора XAML обычно предпочитают технику обработки экземпляров вместо ключевого слова Handles. Это связано с тем, что настройка обработчика событий в XAML является частью типичного рабочего процесса дизайнера и разработчика, а ключевое слово Handles несовместимо с настройкой обработчиков событий в XAML.
В C++/CX также используется += синтаксис, но существуют отличия от базовой формы C#:
- Инференция делегата не предусмотрена, поэтому для создания экземпляра делегата необходимо использовать ref new.
- Конструктор делегата имеет два параметра и требует целевого объекта в качестве первого параметра. Обычно вы указываете это.
- Конструктор делегата требует адрес метода в качестве второго параметра, поэтому оператор & reference предшествует имени метода.
textBlock1().PointerEntered({this, &MainPage::TextBlock1_PointerEntered });
textBlock1->PointerEntered +=
ref new PointerEventHandler(this, &BlankPage::textBlock1_PointerEntered);
Удаление обработчиков событий в коде
Обычно не требуется удалять обработчики событий в коде, даже если вы добавили их в код. Поведение времени существования объекта для большинства объектов Windows Runtime, таких как страницы и элементы управления, заключается в уничтожении этих объектов при их отключении от главного окна и его визуального дерева, а все ссылки на делегаты также уничтожаются. .NET делает это с помощью сборки мусора и среды выполнения Windows с C++/CX по умолчанию использует слабые ссылки.
В некоторых редких случаях требуется явно удалить обработчики событий. К ним относятся:
- Обработчики, добавленные для статических событий, которые не могут получить сбор мусора обычным способом. Примеры статических событий в API среды выполнения Windows — это события классов CompositionTarget и Буфера обмена.
- Тестируйте код, в котором требуется немедленное удаление обработчика или код, в котором необходимо заменить старые или новые обработчики событий для события во время выполнения.
- Реализация пользовательского аксессора для удаления.
- Пользовательские статические события.
- Обработчики навигации по страницам.
FrameworkElement.Unloaded или Page.NavigatedFrom — это возможные триггеры событий, имеющие соответствующие позиции в управлении состоянием и время существования объектов, которые можно использовать для удаления обработчиков для других событий.
Например, можно удалить обработчик событий с именем textBlock1_PointerEntered из целевого объекта textBlock1 с помощью этого кода.
textBlock1.PointerEntered -= textBlock1_PointerEntered;
RemoveHandler textBlock1.PointerEntered, AddressOf textBlock1_PointerEntered
Вы также можете удалить обработчики для случаев, когда событие было добавлено с помощью атрибута XAML, что означает, что обработчик был добавлен в созданный код. Это проще сделать, если вы указали значение Name для элемента, в котором был присоединен обработчик, так как предоставляет ссылку на объект для кода позже; Однако можно также ходить по дереву объектов, чтобы найти необходимую ссылку на объект в случаях, когда объект не имеет имени.
Если необходимо удалить обработчик событий в C++/CX, потребуется маркер регистрации, который должен быть получен из возвращаемого +=
значения регистрации обработчика событий. Это связано с тем, что значение, используемое для правой -=
стороны дерегистрации в синтаксисе C++/CX, является токеном, а не именем метода. Для C++/CX нельзя удалить обработчики, добавленные в качестве атрибута XAML, так как созданный код C++/CX не сохраняет маркер.
Маршрутизируемые события
Среда выполнения Windows поддерживает концепцию перенаправленного события для набора событий, присутствующих в большинстве элементов пользовательского интерфейса. Эти события предназначены для сценариев ввода и взаимодействия с пользователем, и они реализуются в базовом классе UIElement . Ниже приведен список входных событий, которые маршрутичны:
- BringIntoViewRequested
- CharacterReceived
- КонтекстОтменен
- ContextRequested
- DoubleTapped
- DragEnter
- DragLeave
- Перетаскивание
- Начало перетаскивания
- Удалить
- DropCompleted
- Получение фокуса
- GotFocus
- Владение
- KeyDown
- KeyUp
- Потеря фокуса
- LostFocus
- МанипуляцияЗавершена
- ManipulationDelta
- ManipulationInertiaStarting
- ManipulationStarted
- Начало манипуляции
- NoFocusCandidateFound
- УказательОтменен
- ПотеряЗахватаУказателя
- Указатель вошёл
- PointerExited
- PointerMoved
- PointerPressed
- PointerReleased
- PointerWheelChanged
- PreviewKeyDown
- PreviewKeyUp
- PointerWheelChanged
- RightTapped
- Нажато
Перенаправленное событие — это событие, которое потенциально передается (перенаправлено) от дочернего объекта к каждому из его последовательных родительских объектов в дереве объектов. Структура XAML вашего пользовательского интерфейса приближается к этой структуре, где корень этого дерева является корневым элементом в XAML. Дерево истинных объектов может несколько отличаться от вложенного элемента XAML, так как дерево объектов не включает функции языка XAML, такие как теги элементов свойства. Вы можете представить маршрутизируемое событие как всплывающее от любого дочернего элемента элемента XAML, который инициирует событие, к родительскому элементу, который его содержит. Событие и его данные события можно обрабатывать на нескольких объектах вдоль маршрута событий. Если у элемента нет обработчиков, маршрут потенциально будет продолжаться до достижения корневого элемента.
Если вы знаете веб-технологии, такие как Динамический HTML (DHTML) или HTML5, возможно, вы уже знакомы с понятием всплытия событий.
При всплывающем событии по его маршруту все подключенные обработчики событий получают доступ к общему экземпляру данных события. Таким образом, если любой из данных события может записываться обработчиком, любые изменения, внесенные в данные события, будут переданы следующему обработчику и больше не могут представлять исходные данные события из события. Если у события есть маршрутизируемое поведение, референсная документация будет включать заметки или другие примечания о таком поведении.
Свойство OriginalSourceRoutedEventArgs
Когда событие поднимается по маршруту событий, отправитель больше не тот же объект, что и объект, вызывающий событие. Вместо этого отправитель — это объект, к которому прикреплен вызываемый обработчик.
В некоторых случаях отправитель не представляет интереса, и вместо этого вас интересует информация, например, над каким из возможных дочерних объектов находится указатель в момент срабатывания события указателя, или какой объект в большом пользовательском интерфейсе удерживает фокус, когда пользователь нажимает клавишу на клавиатуре. В таких случаях можно использовать значение свойства OriginalSource . Во всех точках маршрута OriginalSource сообщает исходный объект, который запустил событие, а не объект, в котором подключен обработчик. Однако для событий ввода UIElement исходный объект часто является объектом, который не сразу отображается в XAML определения пользовательского интерфейса на уровне страницы. Вместо этого исходный исходный объект может быть шаблонной частью элемента управления. Например, если пользователь наведёт указатель на самый край кнопки, для большинства событий указателя OriginalSource — это часть шаблона Border внутри шаблона, а не сама кнопка.
Совет Всплытие событий ввода особенно полезно, если вы создаете шаблонный элемент управления. Любой элемент управления, имеющий шаблон, может иметь новый шаблон, примененный его потребителем. Потребитель, пытающийся воссоздать рабочий шаблон, может непреднамеренно исключить некоторые обработки событий, объявленные в шаблоне по умолчанию. Вы по-прежнему можете выполнить обработку событий на уровне управления, подключив обработчики как часть переопределения OnApplyTemplate в определении класса. Затем вы можете перехватывать входные события, которые всплывают в корневой элемент управления при создании экземпляра.
Свойство Handled
Несколько классов данных событий для определенных перенаправленных событий содержат свойство Handled. Примеры см. в PointerRoutedEventArgs.Handled, KeyRoutedEventArgs.Handled, DragEventArgs.Handled. Во всех случаях Handled — это назначаемое логическое свойство.
Установка свойства Handled в true влияет на поведение системы событий. Если Handled имеет значение true, маршрутизация останавливается для большинства обработчиков событий; событие не продолжается по маршруту, чтобы уведомить другие подключенные обработчики об этом конкретном случае события. Что означает "обработано" в контексте этого события и как ваше приложение на него реагирует, зависит от вас. По сути, Handled — это простой протокол, который позволяет коду приложения указывать, что произошедшее событие не должно передаваться далее в контейнеры, так как логика вашего приложения уже обработала необходимые действия. Однако, необходимо внимательно следить за тем, чтобы не обрабатывать события, которые, вероятно, должны распространяться, чтобы встроенные системные или управляющие механизмы могли работать. Например, обработка событий низкого уровня в компонентах или элементах выбора может нанести ущерб. Элемент управления выбора может искать входные события, чтобы узнать, что выбор должен измениться.
Не все маршрутизированные события могут отменять маршрут таким образом, это можно определить по тому, что у них нет свойства Handled. Например, GotFocus и LostFocus делают пузырьки, но они всегда пузырятся до корня, и их классы данных событий не имеют свойства Handled , которые могут повлиять на это поведение.
Обработчики событий ввода в элементах управления
В некоторых элементах управления среды выполнения Windows иногда используется концепция "Обработанная " для внутренних событий ввода. Это может показаться как входное событие никогда не происходит, так как пользовательский код не может его обрабатывать. Например, класс Button включает логику, которая намеренно обрабатывает общее входное событие PointerPressed. Это происходит потому, что кнопки вызывают событие Click, инициируемое нажатием указателя, а также другими режимами ввода, такими как нажатие клавиш, например клавиши Enter, которая может активировать кнопку, когда она в фокусе. Для целей проектирования класса Button событие необработанных входных данных обрабатывается в концептуальном смысле, а потребители класса, такие как ваш пользовательский код, могут вместо этого взаимодействовать с событием Click, которое относится к элементу управления. Разделы для определенных классов элементов управления в справочнике по API среды выполнения Windows часто отмечают поведение обработки событий, которое реализует класс. В некоторых случаях можно изменить поведение, переопределив методы OnEvent. Например, можно изменить способ реакции производного класса TextBox на входные данные ключа, переопределив Control.OnKeyDown.
Регистрация обработчиков для уже обслуживаемых маршрутизируемых событий
Ранее мы сказали, что установка Handled в true предотвращает вызов большинства обработчиков. Но метод AddHandler предоставляет способ, при котором можно подключить обработчик, который всегда вызывается для маршрута, даже если другой обработчик ранее в маршруте установил значение Handled в true в данных общего события. Этот метод полезен, если используется элемент управления, обрабатывающий событие во внутреннем компосте или для логики для конкретного элемента управления. но вы по-прежнему хотите ответить на него из экземпляра элемента управления или пользовательского интерфейса приложения. Но используйте этот метод с осторожностью, так как он может противоречить цели handled и, возможно, нарушить предполагаемое взаимодействие элемента управления.
Только перенаправленные события, имеющие соответствующий идентификатор перенаправленного события, могут использовать метод обработки событий AddHandler , так как идентификатор является обязательным вводом метода AddHandler . Справочная документация по AddHandler содержит список событий, для которых доступны идентификаторы маршрутизируемых событий. По большей части это тот же список маршрутизированных событий, что мы показали вам ранее. Исключением является то, что последние два в списке: GotFocus и LostFocus не имеют перенаправленного идентификатора события, поэтому для них нельзя использовать AddHandler .
Маршрутизируемые события вне визуального дерева
Некоторые объекты взаимодействуют с основным визуальным деревом, что концептуально похоже на наложение на основной визуальный контент. Эти объекты не являются частью обычных родительско-дочерних отношений, которые соединяют все элементы дерева с визуальным корнем. Это касается любого отображаемого всплывающего окна или подсказки. Если вы хотите обрабатывать маршрутизированные события от Popup или ToolTip, разместите обработчики на определённые элементы пользовательского интерфейса внутри Popup или ToolTip, а не на самих элементах Popup или ToolTip. Не полагайтесь на маршрутизацию внутри любой компоновки, выполняемой для содержимого всплывающего окна или подсказки. Это связано с тем, что маршрутизация происходит только вдоль основного визуального дерева для маршрутизируемых событий. Всплывающее окно или подсказка не считается родительским элементом дочерних элементов пользовательского интерфейса и никогда не получает маршрутизируемое событие, даже если она пытается использовать фон Всплывающего окна по умолчанию в качестве области захвата для входных событий.
Тестирование попаданий и входные события
Определение того, видно ли элемент в пользовательском интерфейсе для ввода с мыши, касания и пера, называется проверкой на попадание. Для действий касания, а также для событий взаимодействия или манипуляций, которые являются последствиями сенсорного действия, элемент должен быть видимым, чтобы быть источником события и запускать событие, связанное с действием. В противном случае действие передается через элемент в любые базовые элементы или родительские элементы в визуальном дереве, которые могли взаимодействовать с данными входными данными. Существует несколько факторов, влияющих на проверку попадания, но можно определить, может ли данный элемент вызывать события ввода, проверяя его свойство IsHitTestVisible. Это свойство возвращает значение true , только если элемент соответствует этим критериям:
- Значение свойства Видимости элемента — Visible.
- Значение свойства Background или Fill элемента не равно NULL. Значение nullКисти приводит к прозрачности и непроницаемости для тестов на попадание. (Чтобы сделать элемент прозрачным, но и тестируемым, используйте прозрачную кисть вместо null.)
ПримечаниеФон и заливка не определяются UIElement и вместо этого определяются различными производными классами, такими как Control и Shape. Но последствия кистей, используемых для переднего плана и фоновых свойств, одинаковы для событий тестирования попадания и ввода, независимо от того, какой подкласс реализует свойства.
- Если элемент является элементом управления, его значение свойства IsEnabled должно быть true.
- Элемент должен иметь фактические измерения в макете. Элемент, у которого значение ActualHeight и ActualWidth равно 0, не инициирует события ввода.
Некоторые элементы управления имеют специальные правила для определения попадания. Например, TextBlock не имеет свойства Background , но по-прежнему доступен для тестирования в пределах всего региона его измерений. Элементы управления Image и MediaElement доступны для тестирования над определенными размерами прямоугольника, независимо от прозрачного содержимого, например альфа-канала в отображаемом исходном файле мультимедиа. Элементы управления WebView имеют специальное поведение при определении попадания, так как входные данные могут обрабатываться размещённым HTML и вызывать события скрипта.
Большинство классов панели и Границы не тестируются в собственном фоновом режиме, но по-прежнему могут обрабатывать события ввода пользователя, которые направляются из элементов, содержащихся в них.
Вы можете определить, какие элементы находятся в той же позиции, что и событие ввода пользователя, независимо от того, доступны ли элементы для проверки. Для этого вызовите метод FindElementsInHostCoordinates . Как следует из названия, этот метод находит элементы в расположении относительно указанного элемента-хозяина. Однако примененные преобразования и изменения макета могут изменять относительную систему координат элемента и, следовательно, влиять на элементы, найденные в заданном расположении.
Командный
Небольшое количество элементов пользовательского интерфейса поддерживает команду. Команда использует маршрутизированные события, связанные с входными данными, в базовой реализации и предоставляет возможность обработки связанных входных данных пользовательского интерфейса (определенное действие указателя, конкретная клавиша-ускоритель) посредством вызова единственного обработчика команд. Если команда доступна для элемента пользовательского интерфейса, рассмотрите возможность использования интерфейсов API команд вместо каких-либо дискретных событий ввода. Как правило, ссылка на привязку используется в свойствах класса, который определяет модель представления для данных. Свойства содержат именованные команды, реализующие шаблон команд ICommand для конкретного языка. Дополнительные сведения см. в разделе ButtonBase.Command.
Пользовательские события в среде выполнения Windows
Для целей определения пользовательских событий, то, как вы добавляете событие и что это означает для дизайна вашего класса, сильно зависит от используемого языка программирования.
- Для C# и Visual Basic вы определяете событие CLR. Вы можете использовать стандартный шаблон событий .NET, если вы не используете пользовательские методы доступа (добавьте/удаление). Дополнительные советы:
- Для обработчика событий рекомендуется использовать System.EventHandler<TEventArgs>, так как он поддерживает встроенное преобразование в универсальный делегат события среды выполнения Windows EventHandler<T>.
- Не базируйте класс данных событий в System.EventArgs , так как он не преобразуется в среду выполнения Windows. Используйте существующий класс данных событий или вообще обойдитесь без базового класса.
- Если вы используете пользовательские методы доступа, ознакомьтесь с настраиваемыми событиями и средствами доступа к событиям в компонентах среды выполнения Windows.
- Если вы не знаете, что такое стандартный шаблон событий .NET, см. раздел "Определение событий для пользовательских классов Silverlight". Это написано для Microsoft Silverlight, но это по-прежнему хорошая сумма кода и концепций для стандартного шаблона событий .NET.
- Сведения о C++/CX см. в разделе "События" (C++/CX).
- Используйте именованные ссылки даже для ваших собственных применений пользовательских событий. Не используйте лямбда-выражения для пользовательских событий, это может создать циклическую ссылку.
Нельзя объявить пользовательское маршрутизируемое событие для среды выполнения Windows; маршрутизируемые события ограничены набором, поступающим из среды выполнения Windows.
Определение настраиваемого события обычно выполняется в процессе создания пользовательского элемента управления. Это распространенный шаблон, когда у зависимого свойства есть обратный вызов при изменении свойства, а также определено настраиваемое событие, которое может вызываться обратным вызовом зависимого свойства в некоторых или всех случаях. Потребители вашего элемента управления не имеют доступа к обратному вызову для изменения свойства, который вы определили, но наличие доступного события уведомления является следующим лучшим вариантом. Дополнительные сведения см. в разделе "Настраиваемые свойства зависимостей".
Связанные темы
Windows developer