6.Trigger触发器

6.Trigger触发器 .Trigger 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,由于是关键帧动画,所以,我们会看到左侧的菜单区域被缓缓关闭和打开。

 

评论