当使用样式、资源或数据绑定时,发现即使不使用代码,也能完成不少工作。样式,行为以及自定义控件相互互补。

1.样式

1.1基本属性及定义使用

        如何定义及应用样式,如下所示。

// 在App.xaml中定义样式
    <Application.Resources>

        <Style x:Key="BigFontButtonStyle" TargetType="Button">
            <Setter Property="FontFamily" Value="Tiems New Roman"/>
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="Background" Value="BlueViolet"/>
        </Style>
        
    </Application.Resources>

// 在xaml中应用样式
<Button Name="btn" Content="A Tiled Button" Style="{StaticResource BigFontButtonStyle}"
                Height="30" Width="300" Margin="5" Padding="5"
                Click="btn_Click"/>

// 在cs代码中使用样式
private void btn_Click(object sender, RoutedEventArgs e)
{
     btn.Style = (Style)btn.FindResource("BigFontButtonStyle");
}

        样式重要的属性

  • Setter:设置属性值以及自动关联事件处理程序的 Setter对象或 EventSetter 对象的集合
  • Triggers:继承自 TggerBase 类并能自动改变样式设置的对象集合。例如,当另一个属性改变时,或者当发生某个事件时,可以修改样式
  • Resources:希望用于样式的资源集合。例如,可能需要使用一个对象设置多个属性。这时,更高效的做法是作为资源创建对象,然后在 Setter 对象中使用该资源(而不是使用嵌套的标签作为每个Setter 对象的一部分创建对象)
  • BaseOn:通过该属性可创建继承自(并且可以有选择地进行重写)其他样式设置的更具体样式
  • TargetType:该属性标识应用样式的元素的类型。通过该属性可创建只影响特定类型元素的设置器,还可以创建能够为恰当的元素类型自动起作用的设置器

1.2创建样式对象

        样式可以创建的位置:        

  • 样式可以在窗口级别创建,也就是window下直接创建。
  • 可以在布局下创建,如StackPanel或Grid下。
  • 可以在某个控件内创建。
  • 在App.xaml中定义。
  • 在自定义的xaml文件中定义,在使用时引用命名空间。

1.3关联事件处理

        虽然这种可以实现,但基本不太使用。通常使用事件触发器,事件触发器是专为实现动画而设计的,当实现鼠标悬停效果时更有用。

// App.xaml中的样式
        <Style x:Key="MouseOverHighlightStyle" TargetType="TextBlock">
            <EventSetter Event="MouseEnter" Handler="TextBlock_MouseEnter"/>
            <EventSetter Event="MouseLeave" Handler="TextBlock_MouseLeave"/>
            <Setter Property="Padding" Value="5"/>
        </Style>

// xaml中的使用
<TextBlock Text="test" Height="30" Width="300" TextAlignment="Center" 
           MouseEnter="TextBlock_MouseEnter" MouseLeave="TextBlock_MouseLeave"/>

// cs后台代码
        private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
        {
            ((TextBlock)sender).Background = new SolidColorBrush(Colors.LightGoldenrodYellow);
        }

        private void TextBlock_MouseLeave(object sender, MouseEventArgs e)
        {
            ((TextBlock)sender).Background =null;
        }

1.4多层样式

多次样式也就是样式的嵌套,通过BaseOn实现。

            <Style x:Key="BigFontButtonstyle">
                <Setter Property="Control.FontFamily" Value="Times New Roman" />
                <Setter Property="Control.FontSize" Value="18"/>
                <Setter Property="Control.FontWeight" Value="Bold"/>
            </Style>
                
            <Style x:Key="EmphasizedBigFontButtonstyle" 
                   BasedOn="{StaticResource BigFontButtonstyle}">
                    <Setter Property="Control.Foreground" Value="white" />
                    <Setter Property="Control.Background" Value="DarkBlue"/>
            </Style>

1.5通过类型自动应用样式

        只需删除x:Key,设置TargetType=“Button”,则可以将样式应用到所有Button上。

        还可以删除样式,采用Style=“{x:Null}”即可删除样式。

2.触发器

2.1触发器基本

  • 触发器都是System.Windows.TriggerBase的派生类实例。
  • 触发器的优点是不需要为翻转它们而编写任何逻辑,只要停止应用触发器,元素就会恢复到正常外观。
  • 当多个触发器同时触发时,最后一个触发器将起作用。
  • 多个条件都为真时才激活的触发器,可使用MutiTrigger,里面的Conditions。

2.2常用触发器

  • Trigger:这是一种最简单的触发器。可以监测依赖项属性的变化,然后使用设置器改变样式
  • MutiTrigger:与 Trigger 类似,但这种触发器联合了多个条件。只有满足了所有这些条件,才会启动触发器
  • DataTrigger:这种触发器使用数据绑定。与Trigger类似,只不过监视的是任意绑定数据的变化
  • MultiDataTrigger:联合多个数据触发器
  • EventTrigger:这是最复杂的触发器。当事件发生时,这种触发器应用动画。比如下面的动画,当鼠标进入后,0.2s放大字体到22。这种无法自动复原,复原需要编写离开事件触发器。
<Style x:Key="BigFontButtonStyle">
    <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:0.2" Storyboard.TargetProperty="FontSize" To="12"/>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Style.Triggers>
</Style>
06-07 07:08