Общие сведения о событиях и перенаправленных событиях
Важные API
Мы описываем концепцию программирования событий в приложении среда выполнения Windows при использовании расширений компонентов C#, Visual Basic или Visual C++ (C++/CX) в качестве языка программирования и XAML для определения пользовательского интерфейса. Обработчики событий можно назначать как часть объявлений для элементов пользовательского интерфейса в XAML или добавлять обработчики в код. среда выполнения Windows поддерживает перенаправленные события: некоторые входные события и события данных могут обрабатываться объектами за пределами объекта, который вызвал событие. Перенаправленные события полезны при определении шаблонов элементов управления или использовании страниц или контейнеров макетов.
События в качестве концепции программирования
Как правило, понятия событий при программировании приложения среда выполнения Windows похожи на модель событий на самых популярных языках программирования. Если вы знаете, как работать с событиями Microsoft .NET или C++ уже, у вас есть головной запуск. Но вам не нужно знать, что много о концепциях модели событий для выполнения некоторых основных задач, таких как присоединение обработчиков.
При использовании C#, Visual Basic или C++/CX в качестве языка программирования пользовательский интерфейс определяется в разметке (XAML). В синтаксисе разметки XAML некоторые принципы подключения событий между элементами разметки и сущностями кода среды выполнения аналогичны другим веб-технологиям, таким как ASP.NET или HTML5.
Обратите внимание , что код, предоставляющий логику среды выполнения для определяемого XAML пользовательского интерфейса, часто называется кодом позади или файлом программной части. В представлениях решения Microsoft Visual Studio эта связь отображается графически, при этом файл программной части является зависимым и вложенным файлом, а также со ссылкой на страницу XAML.
Button.Click: введение в события и XAML
Одной из наиболее распространенных задач программирования для приложения среда выполнения Windows является запись ввода пользователей в пользовательский интерфейс. Например, в пользовательском интерфейсе может быть кнопка, которую пользователь должен нажать, чтобы отправить сведения или изменить состояние.
Вы определяете пользовательский интерфейс для приложения среда выполнения Windows путем создания XAML. Обычно это выходные данные из области конструктора в Visual Studio. Вы также можете написать XAML в редакторе обычного текста или стороннем редакторе XAML. Создавая этот XAML, можно проводить обработчики событий для отдельных элементов пользовательского интерфейса одновременно, определяя все остальные атрибуты XAML, устанавливающие значения свойств этого элемента пользовательского интерфейса.
Чтобы провести события в XAML, укажите имя строковой формы метода обработчика, который вы уже определили или определите позже в коде. Например, этот 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 в действии сборки интегрированной среды разработки и конечном анализе 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. Обработчик событий уже имеет правильную подпись, включая параметр отправителя и класс данных событий, который использует событие. Кроме того, если метод обработчика с правильной сигнатурой уже существует в коде, имя этого метода отображается в раскрывающемся списке автоматического завершения вместе с параметром <New Event Handler> . Вы также можете нажать клавишу TAB в качестве ярлыка, а не щелкнуть элементы списка IntelliSense.
Определение обработчика событий
Для объектов, которые являются элементами пользовательского интерфейса и объявленными в XAML, код обработчика событий определяется в частичном классе, который служит кодом для страницы XAML. Обработчики событий — это методы, которые записываются в составе частичного класса, связанного с XAML. Эти обработчики событий основаны на делегатах, которые использует конкретное событие. Методы обработчика событий могут быть общедоступными или частными. Закрытый доступ работает, так как обработчик и экземпляр, созданные XAML, в конечном итоге присоединяются к созданию кода. Как правило, рекомендуется сделать методы обработчика событий закрытыми в классе.
Обратите внимание , что обработчики событий для C++ не определяются в частичных классах, они объявляются в заголовке как член частного класса. Действия сборки для проекта C++ заботятся о создании кода, который поддерживает систему типов XAML и модель программной части для C++.
Параметр отправителя и данные события
Обработчик, который вы пишете для события, может получить доступ к двум значениям, доступным в качестве входных данных для каждого случая, когда вызывается обработчик. Первым таким значением является отправитель, который является ссылкой на объект, в котором подключен обработчик. Параметр отправителя вводится в качестве базового типа объекта. Распространенный способ — приведение отправителя к более точному типу. Этот метод полезен, если вы ожидаете проверить или изменить состояние самого объекта отправителя . На основе собственного дизайна приложения обычно вы знаете тип, который безопасно приведения отправителя , в зависимости от того, где связан обработчик или другие особенности проектирования.
Второе значение — это данные событий, которые обычно отображаются в определениях синтаксиса в качестве параметра e . Вы можете узнать, какие свойства для данных событий доступны, просмотрев параметр e делегата, назначенный для конкретного события, которое вы обрабатываете, а затем с помощью IntelliSense или обозревателя объектов в Visual Studio. Вы также можете использовать справочную документацию по среда выполнения Windows.
Для некоторых событий значения свойств определенных свойств данных события являются столь важными, как зная, что произошло событие. Это особенно верно для входных событий. Для событий указателя положение указателя при возникновении события может быть важным. Для событий клавиатуры все возможные клавиши запускают событие KeyDown и KeyUp. Чтобы определить, какой ключ нажимается пользователем, необходимо получить доступ к keyRoutedEventArgs , который доступен обработчику событий. Дополнительные сведения об обработке событий ввода см. в разделе "Взаимодействие с клавиатурой " и ввод указателя указателя. События ввода и сценарии ввода часто имеют дополнительные рекомендации, которые не рассматриваются в этом разделе, например запись указателя для событий указателя, а также клавиши модификатора и коды ключей платформы для событий клавиатуры.
Обработчики событий, использующие асинхронный шаблон
В некоторых случаях вы хотите использовать API, использующие асинхронный шаблон в обработчике событий. Например, можно использовать кнопку на панели приложений для отображения средства выбора файлов и взаимодействия с ним. Однако многие API средства выбора файлов являются асинхронными. Они должны вызываться в пределах асинхронной или ожидаемой области, и компилятор будет применять это. Таким образом, что можно сделать, добавьте асинхронное ключевое слово в обработчик событий, чтобы обработчик теперь асинхронный пустот. Теперь обработчик событий может выполнять асинхронные или ожидаемые вызовы.
Пример обработки событий взаимодействия с пользователем с помощью асинхронного шаблона см. в статье "Доступ к файлам и средства выбора" (частьпервого приложения среда выполнения Windows с помощью серии C# или Visual Basic). См. также [вызов асинхронных API в C).
Добавление обработчиков событий в код
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 . В этом случае для присоединения других обработчиков событий на основе времени существования объекта не требуется; При компиляции страницы 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#:
- Вывод делегата не существует, поэтому необходимо использовать ссылку на новый экземпляр делегата.
- Конструктор делегата имеет два параметра и требует целевого объекта в качестве первого параметра. Обычно это указано.
- Конструктор делегата требует адрес метода в качестве второго параметра, поэтому оператор & reference предшествует имени метода.
textBlock1().PointerEntered({this, &MainPage::TextBlock1_PointerEntered });
textBlock1->PointerEntered +=
ref new PointerEventHandler(this, &BlankPage::textBlock1_PointerEntered);
Удаление обработчиков событий в коде
Обычно не требуется удалять обработчики событий в коде, даже если вы добавили их в код. Поведение времени существования объекта для большинства среда выполнения Windows объектов, таких как страницы и элементы управления, будут уничтожать объекты при отключении от основного окна и его визуального дерева, а все ссылки на делегаты также уничтожаются. .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 с C#, Microsoft Visual Basic или C++/CX поддерживает концепцию перенаправленного события для набора событий, присутствующих в большинстве элементов пользовательского интерфейса. Эти события предназначены для сценариев ввода и взаимодействия с пользователем, и они реализуются в базовом классе UIElement . Ниже приведен список входных событий, которые маршрутичны:
- BringIntoViewRequested
- CharacterReceived
- ContextCanceled
- ContextRequested
- DoubleTapped
- Перетаскивание
- Перетаскивание
- Перетаскивание
- Перетаскивание
- Drop
- DropCompleted
- ПолучениеFocus
- GotFocus
- Владение
- KeyDown
- KeyUp
- Проигрыш Фокус
- LostFocus
- МанипуляцииCompleted
- ManipulationDelta
- ManipulationInertiaStarting
- ManipulationStarted
- Управление запуском
- NoFocusCandidateFound
- PointerCanceled
- PointerCaptureLost
- Указатель введите
- PointerExited
- PointerMoved
- PointerPressed
- PointerReleased
- PointerWheelChanged
- PreviewKeyDown
- PreviewKeyUp
- PointerWheelChanged
- RightTapped
- Резьбовое
Перенаправленное событие — это событие, которое потенциально передается (перенаправлено) от дочернего объекта к каждому из его последовательных родительских объектов в дереве объектов. Структура XAML пользовательского интерфейса приблизит это дерево с корнем этого дерева, являющегося корневым элементом в XAML. Дерево истинных объектов может несколько отличаться от вложенного элемента XAML, так как дерево объектов не включает функции языка XAML, такие как теги элементов свойства. Вы можете представить перенаправленное событие как пузырьки из любого дочернего элемента объекта XAML, который вызывает событие, к родительскому элементу объекта, который содержит его. Событие и его данные события можно обрабатывать на нескольких объектах вдоль маршрута событий. Если у элемента нет обработчиков, маршрут потенциально будет продолжаться до достижения корневого элемента.
Если вы знаете веб-технологии, такие как Динамический HTML (DHTML) или HTML5, возможно, вы уже знакомы с понятием событий.
При перенаправляемом событии через маршрут событий все вложенные обработчики событий получают доступ к общему экземпляру данных события. Таким образом, если любой из данных события может записываться обработчиком, любые изменения, внесенные в данные события, будут переданы следующему обработчику и больше не могут представлять исходные данные события из события. Если событие имеет перенаправленное поведение события, справочная документация будет включать примечания или другие нотации о перенаправленном поведении.
Свойство OriginalSource routedEventArgs
Когда событие пузырится на маршруте событий, отправитель больше не тот же объект, что и объект вызова событий. Вместо этого отправитель — это объект, в котором вызывается обработчик.
В некоторых случаях отправитель не интересен, и вы вместо этого заинтересованы в информации, например о том, какие из возможных дочерних объектов указатель выполняется при срабатывании события указателя или объект в большом пользовательском интерфейсе, удерживаемого фокусом при нажатии клавиши клавиатуры. В таких случаях можно использовать значение свойства OriginalSource . Во всех точках маршрута OriginalSource сообщает исходный объект, который запустил событие, а не объект, в котором подключен обработчик. Однако для событий ввода UIElement исходный объект часто является объектом, который не сразу отображается в XAML определения пользовательского интерфейса на уровне страницы. Вместо этого исходный исходный объект может быть шаблонной частью элемента управления. Например, если пользователь наведите указатель на самую границу кнопки, для большинства событий указателя OriginalSource — это часть шаблона Border в шаблоне, а не сама кнопка.
Если вы создаете шаблонный элемент управления, особенно полезное событие ввода подсказки . Любой элемент управления, имеющий шаблон, может иметь новый шаблон, примененный его потребителем. Потребитель, пытающийся воссоздать рабочий шаблон, может непреднамеренно исключить некоторые обработки событий, объявленные в шаблоне по умолчанию. Вы по-прежнему можете предоставить обработку событий уровня управления, подключив обработчики в рамках переопределения OnApplyTemplate в определении класса. Затем вы можете перехватывать входные события, которые пузырькнуться до корневого элемента управления при создании экземпляра.
Свойство Handled
Несколько классов данных событий для определенных перенаправленных событий содержат свойство Handled. Примеры см. в разделе PointerRoutedEventArgs.Handled, KeyRoutedEventArgs.Handled, DragEventArgs.Handled. Во всех случаях Handled — это логическое свойство settable.
Задание свойства Handled значение true влияет на поведение системы событий. Если обработано значение true, маршрутизация останавливается для большинства обработчиков событий; событие не продолжается по маршруту, чтобы уведомить других подключенных обработчиков этого конкретного события. Что означает "обработано" в контексте события и как ваше приложение реагирует на него. В основном, Handled — это простой протокол, который позволяет коду приложения утверждать, что вхождение события не требуется пузырьков в каких-либо контейнерах, логика приложения позаботилась о том, что нужно сделать. И наоборот, вы должны быть осторожны, что вы не обрабатываете события, которые, вероятно, должны пузыриться, чтобы встроенные системные или управляющие поведения могли действовать. Например, обработка событий низкого уровня в частях или элементах элемента управления выбором может быть вредной. Элемент управления выбора может искать входные события, чтобы узнать, что выбор должен измениться.
Не все перенаправленные события могут отменять маршрут таким образом, и вы можете сказать, что, поскольку у них нет свойства Handled . Например, GotFocus и LostFocus делают пузырьки, но они всегда пузырятся до корня, и их классы данных событий не имеют свойства Handled, которые могут повлиять на это поведение.
Обработчики событий ввода в элементах управления
Некоторые элементы управления среда выполнения Windows иногда используют концепцию "Обработанная" для внутренних событий ввода. Это может показаться как входное событие никогда не происходит, так как пользовательский код не может его обрабатывать. Например, класс Button включает логику, которая намеренно обрабатывает общее входное событие PointerPressed. Это происходит потому, что кнопки запускают событие Click , инициируемое указателем нажатые вводом, а также другими режимами ввода, такими как обработка ключей, таких как клавиши ВВОД, которые могут вызывать кнопку при его фокусе. В целях проектирования класса Button событие необработанных входных данных обрабатывается концептуально, а потребители классов, такие как ваш код пользователя, могут вместо этого взаимодействовать с событием Click, соответствующим элементом управления. Разделы для определенных классов элементов управления в справочнике по API среда выполнения Windows часто отмечают поведение обработки событий, которое реализует класс. В некоторых случаях можно изменить поведение, переопределив методы события On. Например, можно изменить способ реакции производного класса TextBox на входные данные ключа, переопределив Control.OnKeyDown.
Регистрация обработчиков для уже обработанных перенаправленных событий
Ранее мы сказали, что параметр Handled to true предотвращает вызов большинства обработчиков. Но метод AddHandler предоставляет метод, в котором можно подключить обработчик, который всегда вызывается для маршрута, даже если другой обработчик ранее в маршруте задал значение True в данных общего события. Этот метод полезен, если используется элемент управления, обрабатывающий событие во внутреннем компосте или для логики для конкретного элемента управления. но вы по-прежнему хотите ответить на него из экземпляра элемента управления или пользовательского интерфейса приложения. Но используйте этот метод с осторожностью, так как он может противоречить цели handled и, возможно, нарушить предполагаемое взаимодействие элемента управления.
Только перенаправленные события, имеющие соответствующий идентификатор перенаправленного события, могут использовать метод обработки событий AddHandler, так как идентификатор является обязательным вводом метода AddHandler. Справочная документация по AddHandler содержит список событий с доступными идентификаторами перенаправленных событий. По большей части это тот же список перенаправленных событий, которые мы показали ранее. Исключением является то, что последние два в списке: GotFocus и LostFocus не имеют перенаправленного идентификатора события, поэтому для них нельзя использовать AddHandler.
Перенаправленные события вне визуального дерева
Некоторые объекты участвуют в связи с основным визуальным деревом, которое концептуально похоже на наложение на основные визуальные элементы. Эти объекты не являются частью обычных связей родительско-дочерних элементов, которые соединяют все элементы дерева с визуальным корнем. Это касается любого отображаемого всплывающего окна или подсказки. Если вы хотите обрабатывать перенаправленные события из всплывающей подсказки или подсказки, поместите обработчики на определенные элементы пользовательского интерфейса, которые находятся в всплывающей или всплывающей подсказке, а не в самих элементах всплывающей подсказки или подсказки. Не полагаться на маршрутизацию внутри какого-либо компостирования, выполняемого для содержимого всплывающей подсказки или подсказки . Это связано с тем, что маршрутизация событий для перенаправленных событий работает только вдоль основного визуального дерева. Всплывающее окно или подсказка не считается родительским элементом дочерних элементов пользовательского интерфейса и никогда не получает перенаправленное событие, даже если он пытается использовать фон всплывающего окна по умолчанию в качестве области записи для входных событий.
Тестирование попаданий и входные события
Определение того, является ли элемент в пользовательском интерфейсе видимым для мыши, касания и пера ввода вызывается тестирование попаданий. Для действий касания, а также для событий взаимодействия или манипуляций, которые являются последствиями сенсорного действия, элемент должен быть видимым, чтобы быть источником события и запускать событие, связанное с действием. В противном случае действие передается через элемент в любые базовые элементы или родительские элементы в визуальном дереве, которые могли взаимодействовать с данными входными данными. Существует несколько факторов, влияющих на тестирование попаданий, но можно определить, может ли данный элемент запускать события ввода, проверяя его свойство 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.
Определение настраиваемого события обычно выполняется в рамках упражнения определения пользовательского элемента управления. Это общий шаблон для свойства зависимостей, которое имеет обратный вызов с измененным свойством, а также для определения настраиваемого события, вызываемого обратным вызовом свойства зависимостей в некоторых или всех случаях. Потребители элемента управления не имеют доступа к определенному обратному вызову с измененным свойством, но наличие события уведомления доступно в следующем лучшем случае. Дополнительные сведения см. в разделе "Настраиваемые свойства зависимостей".