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


Триггеры

Browse sample. Обзор примера

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

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

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

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

В следующем примере показано Trigger , что при получении фокуса Entry изменяется цвет фона:

<Entry Placeholder="Enter name">
    <Entry.Triggers>
        <Trigger TargetType="Entry"
                 Property="IsFocused"
                 Value="True">
            <Setter Property="BackgroundColor"
                    Value="Yellow" />
            <!-- Multiple Setter elements are allowed -->
        </Trigger>
    </Entry.Triggers>
</Entry>

Объявление триггера указывает следующее:

  • TargetType — тип элемента управления, к которому применяется триггер.
  • Property — свойство, отслеживаемое элементом управления.
  • Value — значение, когда оно происходит для отслеживаемого свойства, которое приводит к активации триггера.
  • Setter — коллекция элементов, применяемых Setter при выполнении условия триггера.

Кроме того, можно указать необязательные EnterActions и ExitActions коллекции. Дополнительные сведения см. в разделе EnterActions и ExitActions.

Применение триггера с помощью стиля

Триггеры также можно добавлять в объявление Style в элементе управления в ResourceDictionary на странице или в приложении. В следующем примере объявляется неявный стиль для всех Entry элементов управления на странице:

<ContentPage.Resources>
    <Style TargetType="Entry">
        <Style.Triggers>
            <Trigger TargetType="Entry"
                     Property="IsFocused"
                     Value="True">
                <Setter Property="BackgroundColor"
                        Value="Yellow" />
                <!-- Multiple Setter elements are allowed -->
            </Trigger>
        </Style.Triggers>
    </Style>
</ContentPage.Resources>

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

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

В следующем примере показано DataTrigger , что отключает Button время, когда пустое Entry :

<Entry x:Name="entry"
       Text=""
       Placeholder="Enter text" />
<Button Text="Save">
    <Button.Triggers>
        <DataTrigger TargetType="Button"
                     Binding="{Binding Source={x:Reference entry},
                                       Path=Text.Length}"
                     Value="0">
            <Setter Property="IsEnabled"
                    Value="False" />
            <!-- Multiple Setter elements are allowed -->
        </DataTrigger>
    </Button.Triggers>
</Button>

В этом примере, если длина Entry равно нулю, активируется триггер.

Совет

При оценке Path=Text.Length всегда укажите значение по умолчанию для целевого свойства (например, Text=""), так как в противном случае это будет null , и триггер не будет работать, как ожидается.

Кроме того, можно указать необязательные EnterActions и ExitActions коллекции. Дополнительные сведения см. в разделе EnterActions и ExitActions.

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

Представляет EventTrigger триггер, который применяет набор действий в ответ на событие. В отличие Triggerот того, EventTrigger не имеет понятия о прекращении состояния, поэтому действия не будут отменены после того, как условие, вызвавшее событие, больше не является истинным.

Требуется EventTrigger задать только Event свойство:

<EventTrigger Event="TextChanged">
    <local:NumericValidationTriggerAction />
</EventTrigger>

В этом примере нет Setter элементов. Вместо этого есть NumericalValidationTriggerAction объект.

Примечание.

Триггеры событий не поддерживаются EnterActions и ExitActions.

Реализация действия триггера должна:

  • Реализация универсального класса TriggerAction<T> с универсальным параметром, соответствующим типу элемента управления, к которому будет применяться триггер. Можно использовать классы, такие как VisualElement запись действий триггера, которые работают с различными элементами управления, или указать тип элемента управления, например Entry.
  • Переопределите метод Invoke. Этот метод вызывается всякий раз, когда происходит событие триггера.
  • При необходимости предоставляют свойства, которые можно задать в XAML при объявлении триггера.

В следующем примере показан NumericValidationTriggerAction класс:

public class NumericValidationTriggerAction : TriggerAction<Entry>
{
    protected override void Invoke(Entry entry)
    {
        double result;
        bool isValid = Double.TryParse(entry.Text, out result);
        entry.TextColor = isValid ? Colors.Black : Colors.Red;
    }
}

Предупреждение

Будьте осторожны при совместном использовании триггеров в объекте ResourceDictionary. Один экземпляр будет совместно использоваться между элементами управления, поэтому любое состояние, настроенное один раз, будет применяться ко всем элементам управления.

Несколько триггеров

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

В следующем примере показано, что привязка MultiTrigger к двум Entry объектам:

<Entry x:Name="email"
       Text="" />
<Entry x:Name="phone"
       Text="" />
<Button Text="Save">
    <Button.Triggers>
        <MultiTrigger TargetType="Button">
            <MultiTrigger.Conditions>
                <BindingCondition Binding="{Binding Source={x:Reference email},
                                            Path=Text.Length}"
                                  Value="0" />
                <BindingCondition Binding="{Binding Source={x:Reference phone},
                                            Path=Text.Length}"
                                  Value="0" />
            </MultiTrigger.Conditions>
            <Setter Property="IsEnabled" Value="False" />
            <!-- multiple Setter elements are allowed -->
        </MultiTrigger>
    </Button.Triggers>
</Button>

Кроме того, коллекция MultiTrigger.Conditions также может содержать PropertyCondition объекты:

<PropertyCondition Property="Text"
                   Value="OK" />

EnterActions и ExitActions

Альтернативный подход к реализации изменений при возникновении триггера заключается в указании EnterActions и ExitActions коллекциях и создании TriggerAction<T> реализаций.

Коллекция EnterActions типа IList<TriggerAction>определяет коллекцию, которая будет вызываться при выполнении условия триггера. Коллекция ExitActions типа IList<TriggerAction>определяет коллекцию, которая будет вызываться после того, как условие триггера больше не будет выполнено.

Примечание.

Объекты TriggerAction, определенные в коллекциях EnterActions и ExitActions, игнорируются классом EventTrigger.

В следующем примере показан триггер свойства, указывающий EnterAction и :ExitAction

<Entry Placeholder="Enter job title">
    <Entry.Triggers>
        <Trigger TargetType="Entry"
                 Property="Entry.IsFocused"
                 Value="True">
            <Trigger.EnterActions>
                <local:FadeTriggerAction StartsFrom="0" />
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <local:FadeTriggerAction StartsFrom="1" />
            </Trigger.ExitActions>
        </Trigger>
    </Entry.Triggers>
</Entry>

Реализация действия триггера должна:

  • Реализация универсального класса TriggerAction<T> с универсальным параметром, соответствующим типу элемента управления, к которому будет применяться триггер. Можно использовать классы, такие как VisualElement запись действий триггера, которые работают с различными элементами управления, или указать тип элемента управления, например Entry.
  • Переопределите метод Invoke. Этот метод вызывается всякий раз, когда происходит событие триггера.
  • При необходимости предоставляют свойства, которые можно задать в XAML при объявлении триггера.

В следующем примере показан FadeTriggerAction класс:

public class FadeTriggerAction : TriggerAction<VisualElement>
{
    public int StartsFrom { get; set; }

    protected override void Invoke(VisualElement sender)
    {
        sender.Animate("FadeTriggerAction", new Animation((d) =>
        {
            var val = StartsFrom == 1 ? d : 1 - d;
            sender.BackgroundColor = Color.FromRgb(1, val, 1);
        }),
        length: 1000, // milliseconds
        easing: Easing.Linear);
    }
}

Примечание.

Вы можете предоставить EnterActions и ExitActions также Setter объекты в триггере, но помните, что Setter объекты вызываются немедленно (они не ожидают EnterAction завершения или ExitAction завершения).

Триггеры состояния

Триггеры состояния — это специализированная группа триггеров, определяющих условия применения VisualState.

Триггеры состояния добавляются в коллекцию StateTriggersVisualState. Эта коллекция может содержать один или несколько триггеров состояния. При наличии активных триггеров состояния в коллекции будет применяться VisualState.

При использовании триггеров состояния для управления визуальными состояниями .NET MAUI использует следующие правила приоритета, чтобы определить, какой триггер (и соответствующий VisualState) будет активным:

  1. Любой триггер, производный от StateTriggerBase.
  2. AdaptiveTrigger активируется из-за выполнения условия MinWindowWidth.
  3. AdaptiveTrigger активируется из-за выполнения условия MinWindowHeight.

Если одновременно активны несколько триггеров (например, два пользовательских триггера), то у первого триггера, объявленного в разметке, будет приоритет.

Примечание.

Триггеры состояния можно задать в Style или напрямую в элементах.

Дополнительные сведения о визуальных состояниях см. в разделе "Визуальные состояния".

Триггер состояния

Класс StateTrigger, производный от класса StateTriggerBase, имеет привязываемое свойство IsActive. StateTrigger выполняет изменение VisualState, когда свойство IsActive изменяет значение.

Класс StateTriggerBase, который является базовым классом для всех триггеров состояния, имеет свойство IsActive и событие IsActiveChanged. Это событие возникает при каждом изменении VisualState. Кроме того, класс StateTriggerBase имеет переопределяемые методы OnAttached и OnDetached.

Важно!

Привязываемое свойство StateTrigger.IsActive скрывает унаследованное свойство StateTriggerBase.IsActive.

В следующем примере XAML показан элемент Style, предусматривающий объекты StateTrigger:

<Style TargetType="Grid">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Checked">
                    <VisualState.StateTriggers>
                        <StateTrigger IsActive="{Binding IsToggled}"
                                      IsActiveChanged="OnCheckedStateIsActiveChanged" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Black" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Unchecked">
                    <VisualState.StateTriggers>
                        <StateTrigger IsActive="{Binding IsToggled, Converter={StaticResource inverseBooleanConverter}}"
                                      IsActiveChanged="OnUncheckedStateIsActiveChanged" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

В этом примере неявный элемент Style направлен на объекты Grid. Если у свойства IsToggled привязанного объекта значение true, цвет фона Grid задается черным. Когда у свойства IsToggled привязанного объекта значение false, активируется изменение VisualState, а цвет фона Grid становится белым.

Кроме того, каждый раз, когда VisualState происходит изменение, IsActiveChanged возникает событие для VisualState этого события. Каждый элемент VisualState регистрирует обработчик событий для этого события:

void OnCheckedStateIsActiveChanged(object sender, EventArgs e)
{
    StateTriggerBase stateTrigger = sender as StateTriggerBase;
    Console.WriteLine($"Checked state active: {stateTrigger.IsActive}");
}

void OnUncheckedStateIsActiveChanged(object sender, EventArgs e)
{
    StateTriggerBase stateTrigger = sender as StateTriggerBase;
    Console.WriteLine($"Unchecked state active: {stateTrigger.IsActive}");
}

В этом примере, когда вызывается обработчик IsActiveChanged события, обработчик выводит, является ли активный VisualState или нет. Например, следующие сообщения выводятся в окно консоли при переходе от визуального состояния Checked к визуальному состоянию Unchecked:

Checked state active: False
Unchecked state active: True

Примечание.

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

Адаптивный триггер

AdaptiveTrigger активирует изменение VisualState, когда окно имеет заданную высоту или ширину. Этот триггер имеет два привязываемых свойства:

  • MinWindowHeight типа double, которое указывает минимальную высоту окна, при которой следует применять VisualState.
  • MinWindowWidth типа double, которое указывает минимальную ширину окна, при которой следует применять VisualState.

Примечание.

AdaptiveTrigger является производным от класса StateTriggerBase и может присоединить обработчик событий к событию IsActiveChanged.

В следующем примере XAML показан элемент Style, предусматривающий объекты AdaptiveTrigger:

<Style TargetType="StackLayout">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Vertical">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="0" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="Orientation"
                                Value="Vertical" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Horizontal">
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowWidth="800" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="Orientation"
                                Value="Horizontal" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

В этом примере неявный элемент Style направлен на объекты StackLayout. Если ширина окна — 0–800 аппаратно-независимых единиц, у объектов StackLayout, к которым применяется Style, будет вертикальная ориентация. Если ширина окна равна >800 единицам VisualState , изменения активируются, а StackLayout ориентация изменяется на горизонтальную.

Свойства MinWindowHeight и MinWindowWidth можно использовать независимо друг от друга или совместно. Ниже представлен простой пример XAML для установки обоих свойств:

<AdaptiveTrigger MinWindowWidth="800"
                 MinWindowHeight="1200"/>

В этом примере указывается, AdaptiveTrigger что соответствующее VisualState будет применяться, если текущая ширина окна равна >800 устройствам независимо от устройств, а текущая высота окна равна >1200 единицам, независимым от устройства.

Сравнение триггера состояния

CompareStateTrigger активирует изменение VisualState, если свойство равно определенному значению. Этот триггер имеет два привязываемых свойства:

  • Property типа object указывает свойство, сравниваемое триггером.
  • Value типа object указывает значение, при котором следует применить VisualState.

Примечание.

CompareStateTrigger является производным от класса StateTriggerBase и может присоединить обработчик событий к событию IsActiveChanged.

В следующем примере XAML показан элемент Style, предусматривающий объекты CompareStateTrigger:

<Style TargetType="Grid">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Checked">
                    <VisualState.StateTriggers>
                        <CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}"
                                             Value="True" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Black" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Unchecked">
                    <VisualState.StateTriggers>
                        <CompareStateTrigger Property="{Binding Source={x:Reference checkBox}, Path=IsChecked}"
                                             Value="False" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>
...
<Grid>
    <Frame BackgroundColor="White"
           CornerRadius="12"
           Margin="24"
           HorizontalOptions="Center"
           VerticalOptions="Center">
        <StackLayout Orientation="Horizontal">
            <CheckBox x:Name="checkBox"
                      VerticalOptions="Center" />
            <Label Text="Check the CheckBox to modify the Grid background color."
                   VerticalOptions="Center" />
        </StackLayout>
    </Frame>
</Grid>

В этом примере неявный элемент Style направлен на объекты Grid. Если у свойства IsCheckedCheckBox значение false, устанавливается белый цвет фона Grid. CheckBox.IsChecked Когда свойство становитсяtrue, VisualState активируется изменение, а цвет фона Grid становится черным.

Триггер состояния устройства

DeviceStateTrigger активирует изменение VisualState в зависимости от платформы устройства, на которой работает приложение. У этого триггера одно привязываемое свойство:

  • Device типа string указывает платформу устройства, на которой следует применить VisualState.

Примечание.

DeviceStateTrigger является производным от класса StateTriggerBase и может присоединить обработчик событий к событию IsActiveChanged.

В следующем примере XAML показан элемент Style, предусматривающий объекты DeviceStateTrigger:

<Style x:Key="DeviceStateTriggerPageStyle"
       TargetType="ContentPage">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="iOS">
                    <VisualState.StateTriggers>
                        <DeviceStateTrigger Device="iOS" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Silver" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Android">
                    <VisualState.StateTriggers>
                        <DeviceStateTrigger Device="Android" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="#2196F3" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

В этом примере явный элемент Style направлен на объекты ContentPage. ContentPage объекты, использующие стиль, устанавливают цвет фона на серебро в iOS и бледный синий на Android.

Триггер состояния ориентации

OrientationStateTrigger активирует изменение VisualState при изменении ориентации устройства. У этого триггера одно привязываемое свойство:

Примечание.

OrientationStateTrigger является производным от класса StateTriggerBase и может присоединить обработчик событий к событию IsActiveChanged.

В следующем примере XAML показан элемент Style, предусматривающий объекты OrientationStateTrigger:

<Style x:Key="OrientationStateTriggerPageStyle"
       TargetType="ContentPage">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup>
                <VisualState x:Name="Portrait">
                    <VisualState.StateTriggers>
                        <OrientationStateTrigger Orientation="Portrait" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="Silver" />
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="Landscape">
                    <VisualState.StateTriggers>
                        <OrientationStateTrigger Orientation="Landscape" />
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor"
                                Value="White" />
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

В этом примере явный элемент Style направлен на объекты ContentPage. Объекты ContentPage, использующие этот стиль, устанавливают серебристый цвет фона, если ориентация книжная, и белый — если ориентация альбомная.