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


События изменения свойств

Windows Presentation Foundation (WPF) определяет несколько событий, которые вызываются в ответ на изменение значения свойства. Часто свойством является свойство зависимостей. Самим событием иногда является маршрутизированное событие и иногда — стандартное событие common language runtime (CLR). Определение события зависит от скрипта, так как некоторые изменения свойств маршрутизируются через дерево элементов, тогда как другие, как правило, влияют только на объект, в котором это свойство изменено.

Определение события изменения свойства

Не все события, сообщающие об изменении свойства явным образом, определяются как событие изменения свойства на основании подписи или именования шаблона. Как правило, в описании события в документации software development kit (SDK) указывается, связано ли событие непосредственно с изменением значения свойства и обеспечивает ли оно перекрестные ссылки между свойством и событием.

События RoutedPropertyChanged

Некоторые события используют тип данных события и делегат, который явно используется для событий изменения свойств. Типом данных события является RoutedPropertyChangedEventArgs<T>, а делегатом — RoutedPropertyChangedEventHandler<T>. Данные события и делегат имеют параметр универсального типа, который используется для указания фактического типа изменения свойства при определении обработчика. Данные события содержат два свойства — OldValue и NewValue, которые затем передаются как тип аргумента в данных события.

"Маршрутизированная" часть имени указывает, что измененное событие свойства зарегистрировано как перенаправленное событие. Преимуществом маршрутизированного события изменения свойства является то, что верхний уровень элемента управления может получать события изменения свойств, если свойства дочерних элементов (составные части элемента управления) изменяют значения. Например, можно создать элемент управления, который включает элемент управления RangeBase, такой как Slider. Если значение свойства Value изменяет часть ползунка, может потребоваться обработать эти изменения на родительском элементе управления, а не на этой части.

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

Если свойством является пользовательское свойство зависимостей или если работа выполняется с производным классом, где определен код экземпляра, то нет лучше механизма для отслеживания изменений свойства, чем система свойств, встроенная в WPF, которая выполняет обратный вызов CoerceValueCallback и PropertyChangedCallback. Дополнительные сведения о том, как можно использовать систему свойств WPF для проверки и приведения, см. в разделах Проверка и обратные вызовы свойства зависимостей и Пользовательские свойства зависимостей.

События DependencyPropertyChanged

Другая пара типов, которые являются частью скрипта события изменения свойства, это DependencyPropertyChangedEventArgs и DependencyPropertyChangedEventHandler. События для этих изменений свойств не маршрутизируются, они являются стандартными событиями CLR. Объект DependencyPropertyChangedEventArgs является нестандартным типом отчета о данных события, так как он не унаследован от объекта EventArgs; DependencyPropertyChangedEventArgs представляет собой структуру, а не класс.

События, которые используют DependencyPropertyChangedEventArgs и DependencyPropertyChangedEventHandler, являются более общими, чем события RoutedPropertyChanged. Примером события, которое использует эти типы, является IsMouseCapturedChanged.

Подобно RoutedPropertyChangedEventArgs<T>, DependencyPropertyChangedEventArgs также предоставляет старые и новые значения свойства. То же относится к применению значений; обычно не рекомендуется пытаться изменить значения снова в отправителе в ответ на событие.

Триггеры свойств

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

Свойством для триггера свойства должно быть свойство зависимости. Оно может быть (и часто является) свойством зависимости только для чтения. Хороший показатель, когда свойство зависимости, предоставляемое элементом управления, хотя бы частично предназначено для того, чтобы быть триггером свойства, если имя свойства начинается с «Is». Свойства, имеющие это именование, являются часто логическими свойствами зависимости только для чтения, где основным скриптом для свойства является отчет о состоянии элемента управления, которое может повлиять на пользовательский интерфейс в режиме реального времени и, следовательно, на кандидат триггера свойства.

Некоторые из этих свойств также имеют выделенное событие изменения свойства. Например, свойство IsMouseCaptured имеет значение IsMouseCapturedChanged события изменения свойства. Само свойство является свойством только для чтения со значением, скорректированным системой ввода, которая вызывает событие IsMouseCapturedChanged при каждом изменении в режиме реального времени.

По сравнению с действительным событием изменения свойства, которое использует триггер свойства для изменения свойства, оно имеет некоторые ограничения.

Триггеры свойств работают через логику точного соответствия. Необходимо указать свойство и значение, определяющее конкретное значение, для которого будет действовать триггер. Например: <Setter Property="IsMouseCaptured" Value="true"> ... </Setter>. Из-за этого ограничения, триггер свойства, в основном, будет использоваться для логических свойств или свойств, которые принимают значение перечисления, где задается достаточный диапазон возможных значений, чтобы определить триггер для каждого случая. Или триггеры свойств могут существовать только для специальных значений, например, когда подсчет элементов достигает нуля и не существует триггер, который выполняет вычисление для случаев, когда значение свойства изменяется снова обратно от нуля (вместо триггеров для всех случаев может потребоваться в коде обработчик событий или поведение по умолчанию, которое сбрасывает состояние триггера, когда значение не равно нулю).

Синтаксис триггера свойства является аналогом инструкции if в программировании. Если условием триггера является true, тогда «тело» триггера свойства «выполняется». «Тело» триггера свойства не является кодом, это разметка. Эта разметка ограничена использованием одного или нескольких элементов Setter для задания других свойств объекта, где применяется стиль или шаблон.

Чтобы сместить условие «if» триггера свойства, которое имеет широкий выбор возможных значений, обычно рекомендуется установить это же значение свойства по умолчанию при помощи Setter. Таким образом, объект Trigger, содержащий метод записи свойств, будет иметь приоритет, если условие триггера выполнено, и объект Setter, который находится вне Trigger, будет иметь приоритет всякий раз, когда условие триггера не выполняется.

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

Чтобы получить более подробные сведения о триггерах свойств, см. раздел Стилизация и использование шаблонов.

См. также

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

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

Общие сведения о свойствах зависимости