zoukankan      html  css  js  c++  java
  • 【WPF学习】第三十七章 触发器

      WPF中有个主题,就是以声明方式扩展代码的功能。当使用样式、资源或数据绑定时,将发现即使不使用代码,也能完成不少工作。

      触发器是另一个实现这种功能的例子。使用触发器,可自动完成简单的样式改变,而这通常需要使用样板事件处理逻辑。例如,当属性发生变化时可以进行响应,并自动调整样式。

      触发器通过Style.Triggers集合链接到样式。每个样式都可以有任意多个触发器,而且每个触发器都是System.Windows.TriggerBase的派生类的实例。下表列出了WPF中的选项。

    表 继承自TriggerBase的类

       通过使用FrameworkElement.Triggers集合,可直接为元素应用触发器,而不需要创建样式。但这存在一个相当大的缺陷。这个Triggers集合只支持事件触发器(并非技术上的原因造成了该限制,只是因为WPF团队没时间实现该特性,将来的版本中可能包含该特性)。

    一、简单触发器

      可为任何依赖项属性关联简单触发器。例如,可通过响应Control类的IsFocused、IsMouseOver以及IsPressed属性的变化,创建鼠标悬停效果和焦点效果。

      每个简单触发器都制定了正在监视的属性,以及正在等待的属性值。当该属性值出现时,将应用存储在Trigger.Setters集合中的设置器(但不能使用更复杂的触发器逻辑。例如,比较某个值以查看其是否处于某个范围,或执行某种计算等。对于这些情况,最好使用事件处理程序)。

      下面的触发器等待按钮获得键盘焦点,当获取焦点时会将前景色设置为深红色:

    <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
    
                </Style.Setters>
                <Style.Triggers>
                    <Trigger Property="Control.IsFocused" Value="True">
                        <Setter Property="Control.Foreground" Value="DarkRed" />
                    </Trigger>
                </Style.Triggers>
            </Style>

      触发器的优点是不需要翻转它们而编写任何逻辑。只要停止应用触发器,元素就会恢复到正常外观。在该例中,这意味着只要用户使用Tab键让按钮失去焦点,按钮就会恢复为通常的灰色背景。

      可创建一次应用于同一元素的多个触发器。如果这些触发器设置不同的属性,着鲜红情况就不会出现混乱。然而,如果多个触发器修改同一属性,那么最后的触发器将有效。

      例如,分析下面的触发器,这些触发器根据控件是否焦点、鼠标是否悬停在控件上,以及是否单击了控件,对控件进行修改:

    <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
    
                </Style.Setters>
                <Style.Triggers>
                    <Trigger Property="Control.IsFocused" Value="True">
                        <Setter Property="Control.Foreground" Value="DarkRed" />
                    </Trigger>
                    <Trigger Property="Control.IsMouseOver" Value="True">
                        <Setter Property="Control.Foreground" Value="LightYellow" />
                        <Setter Property="Control.FontWeight" Value="Bold" />
                    </Trigger>
                    <Trigger Property="Button.IsPressed" Value="True">
                        <Setter Property="Control.Foreground" Value="Red" />
                    </Trigger>
                </Style.Triggers>
            </Style>

      显然,鼠标可能悬停在当前具有焦点的按钮上。这不会出现问题,因为这两个触发器修改不同的属性。但如果单击按钮,就有两个不同的触发器试图设置前景色。现在,针对Button.IsPressed属性的触发器胜出,因为它是最后一个触发器,这与哪个触发器首先发生并无完全决定了最终效果。

      如果希望创建只有当几个条件都为真时才激活的触发器,可使用MultiTrigger。这种触发器提供了一个Conditions集合,可通过该集合定义一系列属性和值得组合。在下面的示例中,只有按钮具有焦点而且鼠标悬停在该按钮上时,才会应用格式化信息:

    <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
    
                </Style.Setters>
                <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Control.IsFocused" Value="True"/>
                            <Condition Property="Control.IsMouseOver" Value="True"/>
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter Property="Control.Foreground" Value="DarkRed" />
                        </MultiTrigger.Setters>
                    </MultiTrigger> 
                </Style.Triggers>
            </Style>

      对于这种情况,不必关心声明条件的顺序,因为在改变背景色之前,这些条件都必须保持为真。

      示例完整的XAML如下所示:

    <Window x:Class="Styles.SimpleTriggers"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="SimpleTriggers" Height="300" Width="300">
        <Window.Resources>
            <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
    
                </Style.Setters>
                <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Control.IsFocused" Value="True"/>
                            <Condition Property="Control.IsMouseOver" Value="True"/>
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter Property="Control.Foreground" Value="DarkRed" />
                        </MultiTrigger.Setters>
                    </MultiTrigger> 
                </Style.Triggers>
                <!--<Style.Triggers>
                    <Trigger Property="Control.IsFocused" Value="True">
                        <Setter Property="Control.Foreground" Value="DarkRed" />
                    </Trigger>
                    <Trigger Property="Control.IsMouseOver" Value="True">
                        <Setter Property="Control.Foreground" Value="LightYellow" />
                        <Setter Property="Control.FontWeight" Value="Bold" />
                    </Trigger>
                    <Trigger Property="Button.IsPressed" Value="True">
                        <Setter Property="Control.Foreground" Value="Red" />
                    </Trigger>
                </Style.Triggers>-->
            </Style>
        </Window.Resources>
    
        <StackPanel Margin="5">
            <Button Padding="5" Margin="5"
                Style="{StaticResource BigFontButton}" 
                  >A Customized Button</Button>
            <TextBlock Margin="5">Normal Content.</TextBlock>
            <Button Padding="5" Margin="5"
                >A Normal Button</Button>
            <TextBlock Margin="5">More normal Content.</TextBlock>
            <Button Padding="5" Margin="5"
                Style="{StaticResource BigFontButton}" 
                  >Another Customized Button</Button>
        </StackPanel>
    </Window>
    SimpleTriggers

    二、事件触发器

      普通触发器等到属性发生变化,而事件触发器等待特定的事件被引发。可能会认为此时应使用设置器来改变元素,但情况并非如此。相反,事件触发器要求用户提供一系列修改空间的动作。这些动作通常被用于动画。

      下面的事件触发器等待MouseEnter事件,然后动态改变按钮的FontSize属性从而形成动画效果,在0.2秒得时间内将字体放大到22个单位:

     <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
                    <Setter Property="Control.FontWeight" Value="Bold" />
                </Style.Setters>
    
                <Style.Triggers>
                    <EventTrigger RoutedEvent="Mouse.MouseEnter">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                      Duration="0:0:0.2"
                      Storyboard.TargetProperty="FontSize"
                      To="22"  />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
    
                </Style.Triggers>
            </Style>

      在XAML中,必须在故事般中定义每个动画,故事板为动画提供了事件线。用户可以在故事板事件内部定义希望使用的一个或多个动画对象。每个动画对象执行本质上相同的任务:在一定时期内修改依赖项属性。

      为了恢复字体大小,样式需要使用响应MouseLeave事件的事件触发器,并在整整两秒的时间内将字体尺寸缩小到原始尺寸。对于这种情况,不需要指明目标字体尺寸——如果没有指明该目标,WPF假定希望使用第一次动画之前按钮原来的字体尺寸:

     <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
                    <Setter Property="Control.FontWeight" Value="Bold" />
                </Style.Setters>
    
                <Style.Triggers>
                    
                    <EventTrigger RoutedEvent="Mouse.MouseLeave">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                      Duration="0:0:1"
                      Storyboard.TargetProperty="FontSize"  />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
    
                </Style.Triggers>
            </Style>

      示例的完整XAML如下所示:

    <Window x:Class="Styles.EventTriggers"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="EventTriggers" Height="300" Width="300">
        <Window.Resources>
            <Style x:Key="BigFontButton">
                <Style.Setters>
                    <Setter Property="Control.FontFamily" Value="Times New Roman" />
                    <Setter Property="Control.FontSize" Value="18" />
                    <Setter Property="Control.FontWeight" Value="Bold" />
                </Style.Setters>
    
                <Style.Triggers>
                    <EventTrigger RoutedEvent="Mouse.MouseEnter">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                      Duration="0:0:0.2"
                      Storyboard.TargetProperty="FontSize"
                      To="22"  />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="Mouse.MouseLeave">
                        <EventTrigger.Actions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                      Duration="0:0:1"
                      Storyboard.TargetProperty="FontSize"  />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger.Actions>
                    </EventTrigger>
    
                </Style.Triggers>
            </Style>
    
        </Window.Resources>
    
        <StackPanel Margin="5">
            <Button Padding="5" Margin="5"
                Style="{StaticResource BigFontButton}" 
                  >A Customized Button</Button>
            <TextBlock Margin="5">Normal Content.</TextBlock>
            <Button Padding="5" Margin="5"
                >A Normal Button</Button>
            <TextBlock Margin="5">More normal Content.</TextBlock>
            <Button Padding="5" Margin="5"
                Style="{StaticResource BigFontButton}" 
                  >Another Customized Button</Button>
        </StackPanel>
    </Window>
    EventTriggers
  • 相关阅读:
    lsattr
    lsattr
    lsattr
    lsattr
    Java反射详细介绍
    Java反射详细介绍
    深入分析 Java 中的中文编码问题
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
  • 原文地址:https://www.cnblogs.com/Peter-Luo/p/12293355.html
Copyright © 2011-2022 走看看