触发器是指当满足预设的条件时去执行一些事务的工具,比如我们希望鼠标移到某个按钮上方时,这个按钮的颜色、大小发生一些改变。这个时候,条件是鼠标移到按钮上,执行的事务是改变按钮的颜色和大小。
WPF提供了5种触发器,以满足不同场合下的使用要求。触发器主要运用的场景在Style、ControlTemplate、DataTemplate三个地方。
触发器名称
说明
Trigger
监测依赖属性的变化、触发器生效
MultiTrigger
通过多个条件的设置、达到满足条件、触发器生效
DataTrigger
通过数据的变化、触发器生效
MultiDataTrigger
多个数据条件的触发器
EventTrigger
事件触发器, 触发了某类事件时, 触发器生效。
Trigger示例
<Style x:Key="GreenButtonStyle" TargetType="Button">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="Green"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Margin" Value="3"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Content" Value="鼠标移入"/>
</Trigger>
</Style.Triggers>
</Style>
在按钮的样式中,我们定义了一个触发器,条件是当按钮的IsMouseOver属性等于True时,执行的事务是将按钮的前景色改成红色,同时改变按钮的尺寸。
Trigger触发器的条件应该是当前控件拥有的属性名称
MultiTrigger示例
<CheckBox x:Name="checkbox">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Content" Value="MultiTrigger"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Margin" Value="3"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Content" Value="多条件触发器"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
在上面的例子中,我们通过Style样式设置了CheckBox的Content及其它属性。然后在样式中实例化了一个MultiTrigger多条件触发器,并为其Conditions集合增加了两个条件,分别是IsMouseOver等于True和IsChecked等于True,当条件满足时,会改变CheckBox的前景色为红色,同时,Content变成"多条件触发器"
DataTrigger数据触发器
DataTrigger数据触发器,它会在绑定数据满足指定条件时应用属性值或执行操作
DataTrigger拥有一个Binding属性,表明它可以绑定某个控件的属性,或者是某个ViewModel的属性,Value属性则是表示绑定的属性达到某个值时,触发条件成立,然后去执行Setters集合里面的内容。
<DataGrid ItemsSource="{Binding Persons}" SelectedItem="{Binding Person}" AutoGenerateColumns="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Age}" Value="19">
<Setter Property="Background" Value="LightBlue"/>
</DataTrigger>
<DataTrigger Binding="{Binding Age}" Value="20">
<Setter Property="Background" Value="LightGreen"/>
</DataTrigger>
<DataTrigger Binding="{Binding Age}" Value="21">
<Setter Property="Background" Value="LightCoral"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=_CheckBox,Path=IsChecked}" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="姓名" Binding="{Binding Name}"/>
<DataGridTextColumn Header="年龄" Binding="{Binding Age}"/>
<DataGridTextColumn Header="生日" Binding="{Binding Address}"/>
</DataGrid.Columns>
</DataGrid>
MultiDataTrigger触发器
当学会了DataTrigger数据触发器和MultiTrigger多条件触发器,MultiDataTrigger就比较好理解了,它就是前面两个触发器的结合体
MultiDataTrigger的用法:
<DataGrid ItemsSource="{Binding Persons}" SelectedItem="{Binding Person}" AutoGenerateColumns="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Age}" Value="19">
<Setter Property="Background" Value="LightBlue"/>
</DataTrigger>
<DataTrigger Binding="{Binding Age}" Value="20">
<Setter Property="Background" Value="LightGreen"/>
</DataTrigger>
<DataTrigger Binding="{Binding Age}" Value="21">
<Setter Property="Background" Value="LightCoral"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=_CheckBox,Path=IsChecked}" Value="True">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=Age}" Value="20"/>
<Condition Binding="{Binding Path=Name}" Value="张三"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Bold"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="姓名" Binding="{Binding Name}"/>
<DataGridTextColumn Header="年龄" Binding="{Binding Age}"/>
<DataGridTextColumn Header="生日" Binding="{Binding Address}"/>
</DataGrid.Columns>
</DataGrid>
EventTrigger触发器
EventTrigger,表示某个事件发生时,执行某一组操作,而这一组操作,通常是对当前控件或其它控件的属性做一些改变
<Window.Resources>
<Storyboard x:Key="OnChecked">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="_LeftBorder">
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnchecked">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="_LeftBorder">
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="200"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ToggleButton.Checked" SourceName="_CheckBox">
<BeginStoryboard Storyboard="{StaticResource OnChecked}"/>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Unchecked" SourceName="_CheckBox">
<BeginStoryboard Storyboard="{StaticResource OnUnchecked}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" x:Name="_LeftBorder" Width="188" Background="LightCyan">
<TextBlock Text="菜单区域" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Border Grid.Column="1" x:Name="_RightBorder" >
<CheckBox x:Name="_CheckBox">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Content" Value="开"/>
<Setter Property="Background" Value="LightGreen"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" CornerRadius="60" Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Content" Value="关"/>
</Trigger>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Width" To="60" />
<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Height" To="60" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Width" To="50" />
<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="Height" To="50" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
</Border>
</Grid>
我们为CheckBox控件编写了一个样式,在样式的Triggers集合中,实例化了两个EventTrigger ,对应的事件分别是CheckBox控件MouseEnter和MouseLeave事件,在各自的触发器中又分别实例化了两个DoubleAnimation对象,当鼠标进入时,改变CheckBox的宽度和高度为60,当鼠标移出时,还原为50。
然后,我们来看看DoubleAnimationUsingKeyFrames动画演示。
首先我们在Window.Resources中定义了两个故事板,分别改变_LeftBorder控件的宽度,什么时候执行这两个故事板?这个时候,我们在Window.Triggers中实例化了两个EventTrigger,条件是当_CheckBox的Checked事件触发时,将_LeftBorder控件的宽度改为0,当_CheckBox的UnChecked事件触发器,将_LeftBorder控件的宽度改为188,由于是关键帧动画,所以,我们会看到左侧的菜单区域被缓缓关闭和打开。