码迷,mamicode.com
首页 > Windows程序 > 详细

WPF Template模版之Style【四】

时间:2015-04-19 16:15:25      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:wpf   模版   

      Style直译过来就是“风格”,“样式”。拿人来举例,人的风格指静态的外观和行为举止。同样一个人,如果留平头、穿上足球队的队服、脚蹬战靴,看上去就是一名叱咤球场的运动员;如果让他换一身笔挺的西装、穿上皮靴、再拎上一个公文包,看上去就是一个商务人士。除了从静态外观来判断一个人的风格,我们还会观察他的行为特点。比如遇到困难时,有些人很乐观,照样谈笑风生。有些人很谨慎、仔细分析问题;有些人很悲观、成天哀声叹气,这就是行为风格,行为风格是由外界刺激的反应体现出来的。说到这儿,大家一定能想到一种职业---演员。演员就是靠调整自己的静态的外观和行为风格来饰演各种角色的。

      如果把WPF窗体看作一个舞台,那么窗体上的控件就是一个演员,它们的职责就是在用户界面上按照业务逻辑的需要扮演自己的角色。为了让同一种控件能担起不同的角色,程序员就要为它们设计多种多样的外观样式和行为动作,这就是Style。构成Style最重要的两种元素是SetterTrigger,Setter类帮助我们设置控件的静态外观风格,Trigger则帮助我们设置控件的行为风格。

      Setter,设置器。什么的设置器呢?即属性值。我们给属性赋值的时候一般都采用“属性名=属性值”的形式。Setter类的Property属性用来指明你想为属性的哪个属性赋值;Setter类的Value属性则是你提供的属性值。

      Trigger, 触发器,即当某些条件满足的时候会触发一个行为(比如某些值的变化或动画的发生等)。触发器比较像事件。事件一般由用户操作触发的,而触发器除了有事件触发型的EventTrigger外还有数据变化触发型的Trigger/DataTrigger及多条件触发型MultiTrigger/MultiDataTrigger等。


1. 基本的Trigger


      Trigger是最基本的触发器。类似于Setter,Trigger也有Property和Value两个属性,Property是Trigger关注的属性名称,Value是触发条件。Trigger还有一个Setters属性,此属性是一组Setter,一旦触发条件满足,这组Setter的“属性---值”就会被应用,触发条件不在满足后,各属性值会被还原。
下面这个例子针对的是CheckBox的Style,当CheckBox的IsCheck属性为True时前景色和字体会改变。XAML代码如下:

<Window x:Class="WpfApplication11.wnd11521"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="wnd11521" Height="200" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type CheckBox}">
            <!--当单个条件满足后触发-->
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="FontSize" Value="20"></Setter>
                    <Setter Property="Foreground" Value="Red"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <CheckBox Content="悄悄的我走了"></CheckBox>
        <CheckBox Content="正如我悄悄的来"></CheckBox>
        <CheckBox Content="我挥挥衣袖"></CheckBox>
    </StackPanel>
</Window>
技术分享

2. MultiTrigger


      MultiTrigger是一个很容易让人误解的名字,会让人以为是多个Trigger集成在一起,实际上叫MultiConditionTrigger更合适,因为必须多个条件同时成立才会被触发。MultiTrigger比Trigger多了一个Conditions属性,需要同时成立的条件就放在这个集合当中。让我们稍微改动一下上面的例子:

<Window x:Class="WpfApplication11.wnd11522"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="wnd11522" Height="200" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type CheckBox}">
            <!--当多个条件满足后触发-->
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsChecked" Value="true"></Condition>
                        <Condition Property="Content" Value="正如我悄悄的来"></Condition>
                    </MultiTrigger.Conditions>
                    <Setter Property="FontSize" Value="20"></Setter>
                    <Setter Property="Foreground" Value="Red"></Setter>
                </MultiTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <CheckBox Content="悄悄的我走了"></CheckBox>
        <CheckBox Content="正如我悄悄的来"></CheckBox>
        <CheckBox Content="我挥挥衣袖"></CheckBox>
    </StackPanel>
</Window>
技术分享

3. 由数据触发DataTrigger


      程序中经常会遇到基于数据执行某些判断情况,遇到这种情况我们就可以考虑使用DataTrigger。DataTrigger对象的Binding属性会把数据源源不断的送出来,一旦送出来的值与Value属性一致,DataTrigger即被触发。下面的例子中,当TextBox的Text长度小于7个字符其Border会保持红色。XAML代码如下:

<Window x:Class="WpfApplication11.wnd11523"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication11"
        Title="wnd11523" Height="200" Width="300">
    <Window.Resources>
        <local:Len2BoolConvert x:Key="l2b"></local:Len2BoolConvert>
        <!--数据满足条件后,触发-->
        <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text.Length, Converter={StaticResource l2b}}" 
                             Value="false">
                    <Setter Property="BorderBrush" Value="Red"></Setter>
                    <Setter Property="BorderThickness" Value="1"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBox Margin="5" ></TextBox>
        <TextBox Margin="5" ></TextBox>
    </StackPanel>
</Window>
      为了将控件自身作为数据源,我们使用了RelativeSource,初学者经常认为“不明确指出Source的值Binding就会将自己作为数据的来源”,这是错误的,因为不明确指出Source的值Binding就会把控件的DataContext作为自己的数据来源。Binding的Path设置为Text.Length,即我们关注的是字符串的长度。长度是一个具体的数字,如何基于这个长度值来做判断呢?这就用到了Converter。我们创建如下Converter:

/// <summary>
/// 数据长度转bool类型
/// </summary>
public class Len2BoolConvert:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int len = (int)value;
        return((len > 6)?(true):(false));
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
      经过Converter转换以后,长度值就会变为bool类型值。当TextBox的文本长度小于7时DataTrigger会使用自己一组Setter把TextBox的边框设置为红色。运行效果如下图:

技术分享

4. 由事件触发的EventTrigger


      EventTrigger是触发器中最特殊的一个。首先,它不是由属性值或者数据的变化来触发而是由事件触发;其次,被触发以后它并非应用一组Setter,而是执行一段动画。因此,UI的动画效果往往和EventTrigger相关联。
在下面这个例子中创建一个针对Button的Style,这个Style包含两个EventTrigger,一个由MouseEnter触发,另一个由MouseLeave触发。XAML代码如下:

<Window x:Class="WpfApplication11.wnd1524"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="wnd1524" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type Button}">
            <!--事件触发-->
            <Style.Triggers>
                <!--鼠标进入-->
                <EventTrigger RoutedEvent="MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
                            <DoubleAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <!--鼠标离开-->
                <EventTrigger RoutedEvent="MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>
                            <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Height"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Canvas>
        <Button Width="50" Height="50"></Button>
    </Canvas>
</Window>
技术分享    

      提醒大家一点:虽然在Style里面大量使用触发器,但触发器并非只能应用在Style中-----各种Template也可以拥有自己的触发器,请大家根据需要决定触发器放在Style里面还是Template里面。

WPF Template模版之Style【四】

标签:wpf   模版   

原文地址:http://blog.csdn.net/aoshilang2249/article/details/45129365

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!