1. Trigger
触发器,应用属性值或有条件地执行操作;
1)触发源:控件;
2)触发条件:某属性为某个值,或执行某个事件时;
3)执行操作:更改某个属性值或执行某个事件;
4)举例:当窗口加载时(执行某个事件时),以动画的形式将窗口的大小倍数从 0 到 1 展示(执行某个事件)。
2. Trigger 的分类
1)根据触发器的触发条件,在 WPF 中,触发器的形态可以是:Trigger、DataTrigger、EventTrigger;
2)以及由 Trigger 延伸的 MultiTrigger 和由 DataTrigger 延伸的 MultiDataTrigger;
2.1 Trigger
Trigger 主要用于监测依赖项属性的变化,然后使用设置器改变样式
// 例子1:
<Button Foreground="Red" Width="350" Content="效果">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Height" Value="200"/>
<Style.Triggers>
<!--触发条件:当焦点属性的值为 True 时-->
<Trigger Property="IsFocused" Value="True">
<!--使用设置器更改样式-->
<Setter Property="Height" Value="300"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
// 例子2:
<Button Foreground="Red" Width="350" Content="效果">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Blue"></Setter>
<Trigger.EnterActions>
<!--启动动画并将动画分发给目标对象和属性-->
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
To="500" Duration="0:0:4"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
…
2.2 DataTrigger
跟 Trigger类似,只是它可以绑定到任意数据的变化
<Button Foreground="Red" Width="350" Content="效果">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<!--触发条件:当 name 值为 bt 的控件的焦点属性值为 True 时-->
<DataTrigger Binding="{Binding IsFocused, ElementName=bt}" Value="True">
<Setter Property="Background" Value="Blue"></Setter>
<DataTrigger.EnterActions>
<!--同样的,启动动画并将动画分发给目标对象和属性-->
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
From="100" To="500" Duration="0:0:4"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
…
2.3 EventTrigger
表示应用设置事件以响应操作的触发器,窗口加载时执行动画就是用 EventTrigger 实现的;
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<!--事件触发器:当 window 加载时,触发-->
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<!--同样的,启动动画并将动画分发给目标对象和属性-->
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" From="0" To="100" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
…
2.4 MultiTrigger
Trigger 类似。联合了多个条件,只有满足了所有这些条件,才会启动触发器。
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiTrigger>
<!--当 Content、IsMouseOver 这两个属性为设置的值时,才会触发该触发器-->
<MultiTrigger.Conditions>
<Condition Property="Content" Value="效果"></Condition>
<Condition Property="IsMouseOver" Value="True"></Condition>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Foreground" Value="Red"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
<Style.Triggers>
<Style TargetType="{x:Type Button}">
<Button.Style>
<Button>
MultiDataTrigger 可以参考 DataTrigger 和 MultiTrigger 即可。
…
2.5 补充
1)Style.Triggers 跟 Control.Triggers 的区别:
像上面,可以往 Style.Trigger 里添加 Trigger、DataTrigger、EventTrigger,
但只能往控件里面的 Triggers 添加 EventTrigger:
<Button>
<Button.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" From="0" To="100" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
2)触发器设置样式无效,可能原因:
在控件标签中,已对控件设置过该属性的值。
具体解释:
style 是应用样式给控件,它的优先级低于直接对控件操作的设置,例如:
<Button Width="350" Content="效果">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<!--Button 本身已经对 Width 设置过值,这里的触发器不会生效-->
<Setter Property="Width" Value="100"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
3)Trigger 、 DataTrigger、EventTrigger 负责<触发器执行>的属性
Trigger 、 DataTrigger 可以是 EnterActions、ExitActions,
EnterActions 是触发对象变为活动状态时,通俗来说,就是当该属性的值成为你设置的值时,开始触发器执行,强调的是成为的瞬间;
而 ExitActions 是反过来,当触发对象变为非活动状态时,即当该属性的值从你设置的值到别的值,这个瞬间,开始触发器执行。
而 EventTrigger 的是 Actions,它的时机在发生事件时。
这个可以根据他们的触发条件,慢慢体会体会,先学会用。
内容将同步到微信公众号:广州 WPF 开发