样式

WPF中的样式

介绍

想象一下,你想要创建一个具有独特设计的应用程序。所有的按钮都应该有橙色背景和Italic字体。按照传统的方式完成这些意味着你必须为每个按钮设置Backgroun和FontStyle属性。

<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
    <Button Background="Orange" FontStyle="Italic" Padding="8,4" Margin="4">Styles</Button>
    <Button Background="Orange" FontStyle="Italic" Padding="8,4" Margin="4">are</Button>
    <Button Background="Orange" FontStyle="Italic" Padding="8,4" Margin="4">cool</Button>
</StackPanel>

这段代码既不可维护,也不简短明了。可以使用样式解决这个问题。
样式的概念让你移除了单个用户接口元素所有的属性值,并且合并到一个样式中。样式由Setter的列表组成。如果你应用样式到一个元素上,将会将会设置样式所有的属性为指定值。这个思想跟Web开发的Cascading Style Sheets(CSS)非常类似。
为了确保样式对于控件是可访问的,你必须添加他到资源中。WPF任何一个控件都有一个资源列表,通过可视化树被所有的控件继承。这就是为什么我们必须指定作为唯一资源标识符的Key属性。
为了应用样式到控件上,我们需要设置Style属性到我们的样式上。为了从资源获得它,我们使用静态资源扩展标记。

<Window>
    <Window.Resources>
        <Style x:Key="MyStyle" TargetType="Button">
            <Setter Property="Background" Value="Orange">
            <Setter Property="FontStyle" Value="Italic">
            <Setter Property="Padding" Value="8,4">
            <Setter Property="Margin" Value="4">
        </Style>
    </Window.Resources>

    <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
        <Button Style="{StaticResource MyStyle}">Style</Button>
        <Button Style="{StaticResource MyStyle}">are</Button>
        <Button Style="{StaticResource MyStyle}">cool</Button>
    </StackPanel>
</Window>

我们现在所取得的成就是:

  • 可维护的代码
  • 移除重复
  • 从单点改变一组控件的外观
  • 运行时改变样式的可能

样式继承

WPF中一个样式可以基于其他样式。允许你指定一个基本样式,以设置公共属性和从中派生专门控件。

<Style x:Key="ButtonBaseStyle">
    <Setter Property="FontSize" Value="12">
    <Setter Property="Background" Value="Orange">
</Style>

<Style x:Key="MyButtonStyle" BaseOn="{StaticResource ButtonBaseStyle}">
    <Setter Property="FontWeight" Value="Bold">
</Style>

覆盖默认样式

如果你想要替换控件的默认样式,你可以定义一个类型化样式。类型化央视仅仅拥有一个隐式的key,key是目标类型的Type对象。所有的控件将会自动地从该定义继承样式。

<Style TargetType="Button">
    <Setter Property="FontWeight" Value="Bold"/>
</Style>

样式中的触发器

触发器定义了满足指定条件时触发的Setter的程序列表。WPF已知有三种不同类型的触发器

  • 属性触发器 当属性获取到一个指定值
  • 事件触发器 当指定事件被触发
  • 数据触发器 当绑定表达式达到指定的值

属性触发器

当属性获取到指定值时,属性触发器会激活一个Setter列表。如果值发生改变,触发器会撤销Setter。

<Style TargetType="Button">
    <Setter Property="Background" Value="SkyBlue"/>
    <Setter Property="FontSize" Value="17"/>
    <Setter Property="Foreground" Value="White"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="#e4c6d4"/>
            <Setter Property="FontSize" Value="22"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Foreground" Value="SkyBlue"/>
            <Setter Property="FontSize" Value="17"/>
        </Trigger>
    </Style.Triggers>
</Style>

事件触发器

当某个事件被触发时

<Style TargetType="{x:Type CheckBox}">
    <Setter Property="Foreground" Value="SkyBlue"/>
    <Style.Triggers>
        <EventTrigger RoutedEvent="Mouse.MouseEnter">
        </EventTrigger>
        <EventTrigger RoutedEvent="Mouse.MouseEnter">
        </EventTrigger>
    </Style.Triggers>
</Style>

数据触发器

当绑定的表达式达到某个值

<Style TargetType="TextBox">
    <Style.Triggers>
        <DataTrigger Binding="{Binding User.Status}" Value="2">
            <Setter Property="FontColor" Value="Red">
        </DataTrigger>
    </Style.Triggers>
</Style>

多触发器

当多个条件满足

<Style TargetType="TextBox">
    <Style.Triggers>
        <MultiTrigger.Conditions>
            <Condition Property="IsEnabled" Value="True">
            <Condition Property="Text" Value="Test">
        </MultiTrigger.Conditions>
        <MultiTrigger.Setters>
            <Setter Property="Foreground" Value="Red"/>
        </MultiTrigger.Setters>
    </Style.Triggers>
</Style>

处处使用触发器的技巧

触发器仅在样式和模板中可用。即使每个控件都拥有Triggers属性,也只能与EventTriggers一起使用。如果你想要在样式或者模板外使用普通的触发器,你可以使用一个小小的技巧。只需要用下列代码片段包装你的代码。

<Control>
    <Control.Template>
        <ControlTemplate>
            <!-- 触发器此处可用 -->
        </ControlTemplate>
    </Control.Template>
</Control>
posted @ 2023-08-29 17:28  Juston007  阅读(15)  评论(0)    收藏  举报