6.Trigger触发器
触发器是指当满足预设的条件时去执行一些事务的工具,比如我们希望鼠标移到某个按钮上方时,这个按钮的颜色、大小发生一些改变。这个时候,条件是鼠标移到按钮上,执行的事务是改变按钮的颜色和大小。
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,由于是关键帧动画,所以,我们会看到左侧的菜单区域被缓缓关闭和打开。