XAML中的Style

开发工具与关键技术:Visual Studio 2017、Style

作者:邓崇富

撰写时间:2019 年 5 月 15 日

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

XAML中构成Style最重要的两种元素是SetterTrigger,Setter类帮助我们设置控件的静态外观风格,Trigger类帮助我们设置控件的行为风格。

Style中的Setter:

Setter是设置属性值的设置器。我们给属性赋值的时候一般采用“属性名=属性值”的形式。Setter类的Property属性用来指明你想为目标的哪个属性赋值:

Setter类的value属性则是你提供的属性值。

下面的例子中在Window的资源字典中放置一个针对TextBlockStyle,Style中使用若干Setter来设定TextBlock的一些属性,这样程序中的TextBlock就会具有统一的风格,除非你使用{x:NULL}显示地清空Style

Window的资源字典代码如下:

<!--自定义样式资源-->

    <Window.Resources>

        <Style TargetType="TextBlock">

            <Setter Property="FontSize" Value="24"/>

            <Setter Property="Foreground" Value="Red"/>

            <Setter Property="FontStyle" Value="Italic"/>

        </Style>

    </Window.Resources>

下面是XAML代码:

<Window x:Class="练习1.Page2"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Icon="images\Q.PNG"

        Title="TeamViewer" Height="450" Width="800">

    <Grid>

        <StackPanel Margin="5">

            <TextBlock Text="陌生人你好!"/>

            <TextBlock Text="这里欢迎你!"/>

            <TextBlock Text="这里是Style={x;Null}" Style="{x:Null}"/>

        </StackPanel>

    </Grid>

</Window>

 

运行效果如下:

根据上面的例子我们可以得知,如果想设置控件的ControlTemplate,只需要把SetterProperty设为Template并为Value提供一个ControlTemplate对象即可。

Setter中的Trigger

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

  1. 基本Trigger

Trigger类是最基本的触发器。类似于SetterTrigger也有PropertyValue这个属性PropertyTrigger关注的属性名称,Value是触发条件。Trigger类还有一个Setter属性,此属性值是一组Setter,一旦触发条件满足,这组Setter的“属性一值”就会被应用,触发条件不再满足后,各属性会被还原。

下面这个例子中包含一个针对CheckBoxStyle,当CheckBoxIsChecked属性为true的时候前景色和字体会改变。

下面是资源样式和XAML的代码:

<Window x:Class="练习1.Page2"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Icon="images\Q.PNG"

        Title="TeamViewer" Height="450" Width="800">

   

    <!--自定义样式资源-->

    <Window.Resources>

        <Style TargetType="CheckBox">

            <Style.Triggers>

                <Trigger Property="IsChecked" Value="true">

                    <Setter Property="FontSize" Value="20"/>

                    <Setter Property="Foreground" Value="Orange"/>

                </Trigger>

            </Style.Triggers>

        </Style>

    </Window.Resources>

   

        <StackPanel>

            <CheckBox Content="给我!盘他" Margin="5"/>

            <CheckBox Content="我什么都不敢说" Margin="5"/>

            <CheckBox Content="也不敢问" Margin="5"/>

            <CheckBox Content="瑟瑟发抖" Margin="5"/>

        </StackPanel>

    </Grid>

</Window>

运行效果如下:

  1. MultiTrigger

MultiTriggerTrigger多一个Conditions属性,需要同时成立的条件就存储在这个集合中。

通过稍微改动一下上面的例子,要求同时满足CheckBox被选中且Content为“我什么都不敢说”时会被触发。

XAML代码如下(仅Style部分):

<Style TargetType="CheckBox">

            <Style.Triggers>

                <MultiTrigger>

                    <MultiTrigger.Conditions>

                        <Condition Property="IsChecked" Value="true"/>

                        <Condition Property="Content" Value="我什么都不敢说"/>

                    </MultiTrigger.Conditions>

                    <MultiTrigger.Setters>

                        <Setter Property="FontSize" Value="20"/>

                        <Setter Property="Foreground" Value="Orange"/>

                    </MultiTrigger.Setters>

                </MultiTrigger>

            </Style.Triggers>

        </Style>

运行效果如下:

3由数据触发的DataTrigger

程序中经常会遇到基于数据执行某些判断情况,遇到这种情况时

就可以考虑使用DataTriggerDataTrigger对象的Binding属性会把数据源源不断送过来,一旦送来的值与Value属性一致,DataTrigger即被触发。

下面的例子中,当TextBoxText长度小于7个字符时其Border会保持红色。

XAML代码如下:

<Window.Resources>

        <local:L2BConverter x:Key="cvtr"/>

        <Style TargetType="TextBox">

            <Style.Triggers>

                <DataTrigger

                    Binding="{Binding RelativeSource={x:Static RelativeSource.Self},

                    Path=Text.Length,Converter={StaticResource cvtr}}" Value="false">

                    <Setter Property="BorderBrush" Value="Red"/>

                    <Setter Property="BorderThickness" Value="1"/>

                </DataTrigger>

            </Style.Triggers>

        </Style>

    </Window.Resources>

    <StackPanel>

        <TextBox Margin="5,80,5,5"/>

        <TextBox Margin="5,0"/>

        <TextBox Margin="5"/>

</StackPanel>

上面的例子中需要解释的是DataTriggerBinding。为了将控件自己作为数据源,使用了RelativeSource,不明确指出SourceBinding会把控件的DataContext属性当作数据源。BindingPath被设置为Text.Length,即我们关注的是字符串的长度。长度是一个具体的数字就要用到了Converter来判断。

下面是创建的Converter的代码:

public class L2BConverter : IValueConverter

        {

            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

            {

                int textLength = (int)value;

                return textLength > 6 ? true : false;

            }

 

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

            {

                throw new NotImplementedException();

            }

        }

经过上面的Converter转换后,长度值会转换成布尔类型值。DataTrigger的Value被设置为false,也就是说当TextBox的文本长度小于7时DataTrigger会使用自己的一组Setter把TextBox的边框设置为红色。

运行效果如下:

  1. 由事件触发的EventTrigger

EventTrigger是触发器中最特殊的一个。首先,它不是由属性值或数据的变化来触发而是由事件来触发;其次,被触发后它并非应用一组Setter,而是执行一段动画。因此,UI层的动画效果往往·与EventTrigger相关联。

在下面的例子中创建了一个针对ButtonStyle,这个Style包含两个EventTrigger,一个由MouseEnter事件触发,另一个由MouseLeave事件触发。

XAML代码如下:

<Window.Resources>

        <Style TargetType="Button">

            <Style.Triggers>

                <!--鼠标进入-->

                <EventTrigger RoutedEvent="MouseEnter">

                    <BeginStoryboard>

                        <Storyboard>

                            <DecimalAnimation To="150" Duration="0:0:0.2" Storyboard.TargetProperty="Width"/>

                            <DecimalAnimation 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="40" Height="40" Content="按钮"/>

</Canvas>

 

效果如下:

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值