Сводка по главе 23. Триггеры и реакции на событие

Download Sample Скачайте пример

Примечание.

Эта книга была опубликована весной 2016 года и с тех пор не обновлялась. Многое в этой книге остается ценным, но некоторые материалы устарели, а некоторые разделы перестали быть полностью верными или полными.

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

Для использования триггеров и реакций на событие VisualElement и Style поддерживают два свойства коллекции:

Триггеры

Триггером называется условие (изменение свойства или срабатывание события), которое приводит к некоторому отклику (изменение другого свойства или выполнение некоторого кода). Свойство Triggers для VisualElement и Style имеет тип IList<TriggersBase>. TriggerBase является абстрактным классом, от которого наследуются четыре запечатанных класса:

  • Trigger для ответов на основе изменений свойств;
  • EventTrigger для ответов на основе выполнения событий;
  • DataTrigger для ответов на основе привязки данных;
  • MultiTrigger для ответов на основе нескольких триггеров.

Триггер всегда задается для элемента, свойство которого изменяется этим триггером.

Простейший триггер

Класс Trigger проверяет изменение значения свойства и отвечает, устанавливая другое свойство того же элемента.

Trigger определяет три свойства:

  • Property типа BindableProperty
  • Value типа Object
  • Setters с типом IList<SetterBase> — это свойство содержимого Trigger.

Кроме того, Trigger требует установить следующее свойство, наследуемое от TriggerBase:

  • TargetType, чтобы указывать тип элемента, к которому присоединен Trigger

Здесь Property и Value составляют условие, а коллекция Setters определяет ответ. Если Property имеет значение, указанное в Value, применяются объекты Setter из коллекции Setters. Если Property имеет другое значение, методы задания удаляются. Setter определяет два свойства, которые совпадают с двумя первыми свойствами Trigger:

В примере EntryPop показано, как применение Trigger к Entry позволяет увеличивать размер Entry с помощью свойства Scale, когда свойство IsFocused объекта Entry имеет значение true.

Обычно так не делают, но Trigger можно задавать в коде, как показано в примере EntryPopCode.

Пример StyledTriggers демонстрирует, как задать Trigger из Style для применения к нескольким элементам Entry.

Действия триггера и анимации

Вы также можете выполнять при активации триггера небольшой фрагмент кода. Этот код может быть анимацией, которая использует определенное свойство. Один из распространенных приемов — использовать EventTrigger с определением двух свойств:

  • Event с типом string, где содержится имя события;
  • Actions с типом IList<TriggerAction>, где определен список выполняемых в ответ действий.

Чтобы использовать его, нужно написать производный от TriggerAction<T> класс, обычно это TriggerAction<VisualElement>. Определите свойства в этом классе. Это простые свойства CLR, а не привязываемые свойства, так как TriggerAction не наследует от BindableObject. Необходимо переопределить метод Invoke, который вызывается при активации действия. В качестве аргумента он принимает целевой элемент.

В качестве примера ScaleAction используется класс в библиотеке Xamarin.FormsBook.Toolkit. Он вызывает свойство ScaleTo для анимации свойства Scale указанного элемента. Так как одно из его свойств имеет тип Easing, класс EasingConverter позволяет использовать в XAML стандартные статические поля Easing.

В примере EntrySwell показано, как вызывать ScaleAction из EventTrigger объектов, отслеживающих события Focused и Unfocused.

В примере CustomEasingSwell показано, как определить пользовательскую функцию для реалистичной анимации для ScaleAction в файле кода программной части.

Действия также можно вызывать с помощью Trigger (в отличие от EventTrigger). Для этого необходимо знать, что TriggerBase определяет две коллекции:

Пример EnterExitSwell демонстрирует способ использования этих коллекций.

Дополнительные триггеры событий

Класс ScaleUpAndDownAction из библиотеки Xamarin.FormsBook.Toolkit дважды вызывает ScaleTo для увеличения и уменьшения размера. Пример ButtonGrowth использует этот прием в EventTrigger с примененным стилем, чтобы обеспечить визуальное подтверждение нажатия Button. Эта двойная анимация также поддерживается двумя действиями в коллекции типа DelayedScaleAction.

Класс ShiverAction из библиотеки Xamarin.FormsBook.Toolkit определяет действие дрожания с возможностью настройки. Эта техника демонстрируется в примере ShiverButtonDemo.

Класс NumericValidationAction в библиотеке Xamarin.FormsBook.Toolkit действует только для элементов Entry и присваивает свойству TextColor значение red, если свойство Text не является double. Этот подход демонстрируется в примере TriggerEntryValidation.

Триггеры данных

DataTrigger похож на Trigger, за исключением того, что он отслеживает привязку данных, а не ожидает изменений значения свойства. Это позволяет свойству одного элемента влиять на свойство в другом элементе.

DataTrigger определяет три свойства:

Для примера GenderColors требуется библиотека SchoolOfFineArt. Он задает цвета для имен учащихся: синий или розовый в зависимости от свойства Sex:

Triple screenshot of Gender Colors

В примере ButtonEnabler для свойства IsEnabled элемента Entry устанавливается значение False, если свойство Length свойства Text элемента Entry равно 0. Обратите внимание, что свойство Text инициализируется пустой строкой. По умолчанию оно имеет значение null, при котором DataTrigger не будет работать правильно.

Объединение условий в MultiTrigger

MultiTrigger представляет собой коллекцию условий. Когда они все получают значение true, применяются методы задания. Этот класс определяет два свойства:

Condition является абстрактным классом и имеет два дочерних класса:

В примере AndConditions элемент BoxView выделяется, только если включены все четыре элемента Switch.

В примере OrConditions показано, как можно изменять цвет BoxView при включении любого из четырех элементов Switch. Это требует применения закона де Моргана и обращения всей логики.

Сочетание логики И и ИЛИ реализовать сложнее, и обычно для этого нужны невидимые элементы Switch для промежуточных результатов. В примере XorConditions показано, как включать Button, если один и только один из двух элементов Entry содержит введенный текст.

Поведение

Все, что можно сделать с помощью триггера, можно реализовать и с помощью реакции на событие, но для этого всегда требуется производный от Behavior<T> класс с переопределением следующих двух методов:

В качестве аргумента принимается элемент, к которому присоединяется реакция на событие. Как правило, метод OnAttachedTo присоединяет некоторые обработчики событий, а OnDetachingFrom отсоединяет их. Так как этот класс обычно сохраняет некоторые сведения о состоянии, его нельзя использовать совместно в Style.

Пример BehaviorEntryValidation аналогичен триггеру TriggerEntryValidation, за исключением того, что он использует поведение — NumericValidationBehavior класс в Xamarin.Formsбиблиотеке Book.набор средств.

Реакция на событие с поддержкой свойств

Behavior<T> наследует от Behavior, который наследует от BindableObject, а значит для реакции на событие можно определить привязываемые свойства. Эти свойства можно активно использовать в привязке данных.

Этот подход демонстрируется в программе EmailValidationDemo на основе класса ValidEmailBehavior из библиотеки Xamarin.FormsBook.Toolkit. ValidEmailBehavior имеет привязываемое свойство только для чтения и служит источником в привязках данных.

В примере EmailValidationConv эта же реакция на событие используется для отображения индикатора другого типа, который информирует о допустимом формате адреса электронной почты.

Пример EmailValidationTrigger является модификацией предыдущего примера. ButtonGlide использует DataTrigger в сочетании с той же реакцией на событие.

Переключатели и флажки

Поведение выключателя можно инкапсулировать в классе, например ToggleBehavior из библиотеки Xamarin.FormsBook.Toolkit, а затем определить все визуальные элементы для переключателя полностью в XAML.

В примере ToggleLabel используется ToggleBehavior с DataTrigger, чтобы применить Label с двумя текстовыми строками для переключения.

Пример FormattedTextToggle расширяет эту схему, переключаясь между двумя объектами FormattedString.

Класс ToggleBase в библиотеке Xamarin.FormsBook.Toolkit является производным от ContentView, определяет свойство IsToggled и содержит ToggleBehavior для логики переключения. Это упрощает определение выключателя в XAML, как показано в примере TraditionalCheckBox.

SwitchCloneDemo включает класс, производный SwitchClone от ToggleBase класса и использующий TranslateAction класс для создания кнопки переключения, которая похожа на Xamarin.FormsSwitch.

Класс RotateAction в Xamarin.FormsBook.Toolkit предоставляет анимацию, на которой основан анимированный рычаг в примере LeverToggle.

Реагирование на касания

Недостаток EventTrigger заключается в том, что вы не можете присоединить его к TapGestureRecognizer, чтобы реагировать на касания. Чтобы обойти эту проблему, в библиотеку Xamarin.FormsBook.Toolkit включен TapBehavior.

В примере BoxViewTapShiver используется TapBehavior, чтобы применить описанный выше ShiverAction для нажатых элементов BoxView.

В примере ShiverViews показано, как сократить объем разметки с помощью инкапсуляции класса ShiverView.

Переключатели

Библиотека Xamarin.FormsBook.Toolkit также имеет класс RadioBehavior для создания переключателей, сгруппированных по имени группы string.

Программа RadioLabels использует текстовые строки в качестве переключателя. В примере RadioStyle используется Style, чтобы различать нажатые и не нажатые кнопки. Пример RadioImages использует текстовые строки в качестве переключателей.

Triple screenshot of Radio Images

В примере TraditionalRadios отображаются переключатели традиционного вида с точкой внутри окружности.

Исчезновение и ориентация

В последнем примере MultiColorSliders вы с помощью переключателей можете выбирать любое из трех разных представлений для выбора цвета. Эти три представления плавно появляются и исчезают с использованием FadeEnableAction из библиотеки Xamarin.FormsBook.Toolkit.

Эта программа также реагирует на изменения ориентации (книжная или альбомная) с помощью GridOrientationBehavior из библиотеки Xamarin.FormsBook.Toolkit.