.NET 多平台应用 UI (.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 扩展用于监视指定条件。
以下示例演示了在 Entry 为空时,DataTrigger 禁用 Button 的情况:
<Entry x:Name="entry"
Text=""
Placeholder="Enter text" />
<Button Text="Save">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding x:DataType='Entry',
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 表示应用属性值或执行动作的触发器。 所有条件都必须为 true 之后才能应用 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 x:DataType='Entry',
Source={x:Reference email},
Path=Text.Length}"
Value="0" />
<BindingCondition Binding="{Binding x:DataType='Entry',
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> 实现。
类型为IList<TriggerAction>的EnterActions集合定义了在满足触发条件时将被调用的集合。 当不再满足触发条件时,类型ExitActionsIList<TriggerAction>集合定义了将要调用的集合。
注释
EventTrigger类会忽略定义在EnterActions和ExitActions集合中的TriggerAction对象。
以下示例显示了一个属性触发器,该触发器指定了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 应用条件。
状态触发器已添加到 VisualState 的 StateTriggers 集合中。 此集合可以包含单个状态触发器或多个状态触发器。 当集合中的任何状态触发器处于活动状态时,将应用 A VisualState 。
使用状态触发器控制视觉状态时,.NET MAUI 使用以下优先规则来确定将处于活动状态的触发器(和相应的 VisualState)。
- 派生自 StateTriggerBase. 的任何触发器。
- 由于MinWindowWidth条件被满足,AdaptiveTrigger已被激活。
- 由于MinWindowHeight条件得到满足,AdaptiveTrigger已被激活。
如果多个触发器同时处于活动状态(例如两个自定义触发器),则标记中声明的第一个触发器优先。
注释
可以在元素 Style中或直接在元素中设置状态触发器。
有关视觉状态的详细信息,请参阅 视觉状态。
状态触发器
StateTrigger 类派生自 StateTriggerBase 类,并具有 IsActive 可绑定属性。 属性IsActive更改值时,会触发StateTriggerVisualState更改。
该 StateTriggerBase 类是所有状态触发器的基类,具有属性 IsActive 和事件 IsActiveChanged 。 每当 VisualState 发生更改时,此事件将触发。 此外,StateTriggerBase 类具有 OnAttached 可重写方法和 OnDetached 方法。
重要
StateTrigger.IsActive 可绑定的属性隐藏了继承来的 StateTriggerBase.IsActive 属性。
以下 XAML 示例显示了一个包含StateTrigger对象的Style:
<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 发生更改时,VisualState 的 IsActiveChanged 事件都会被触发。 每个 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 方向更改为水平。
和MinWindowHeightMinWindowWidth属性可以独立使用,也可以彼此结合使用。 以下 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 x:DataType='CheckBox', 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 x:DataType='CheckBox', 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>
<Border BackgroundColor="White"
StrokeShape="RoundRectangle 12"
Margin="24"
Padding="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>
</Border>
</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更改。 此触发器具有单个可绑定属性:
- Orientation,类型 DisplayOrientation,指示 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 使用样式的对象在竖屏模式时背景色设为银色,在横屏模式时背景色设为白色。
浏览示例