样式(Style)是组织和重用格式化选项的重要工具,样式是创建一系列封装所有细节的样式,然后在需要之处通过属性应用这些样式。样式只是应用与元素的属性值集合,WPF样式系统和HTML里面的CSS层叠样式表很相似。如你想让所有的控件显示相同的字体和字体大小,一些控件显示特定的样式等等。
行为(Behavior)是一款重用用户界面代码,使得行为封装了一些通用的UI功能,样式的改变和调整,都会触发行为的产生。
1、如何定义样式?
<Window x:Class="Example.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Example" xmlns:albert="http://www.albert.com" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="st1"> <Setter Property="Control.FontFamily" Value="宋体" ></Setter> <Setter Property="Control.FontSize" Value="33"></Setter> </Style> </Window.Resources> <Grid> <Button Style="{StaticResource ResourceKey=st1}"></Button> </Grid> </Window>
每个style对象都封装了一个setter对象的集合,有时候,属性不仅仅是简单的数字和字符串,也可以用复杂的一些对象来创建样式,如下列示例:
<Window x:Class="Example.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Example" xmlns:albert="http://www.albert.com" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="st1"> <Setter Property="Control.FontFamily" Value="宋体" ></Setter> <Setter Property="Control.FontSize" Value="33"></Setter> <Setter Property="Control.Background"> <Setter.Value> <ImageBrush TileMode="Tile"></ImageBrush> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Button Style="{StaticResource ResourceKey=st1}"></Button> </Grid> </Window>
2、 关联事件处理程序
属性设置器是所有样式中最常见的要素,但是也可以创建事件关联特定事件处理程序EventSetter对象的集合。下面来设定EventSetter。
<Window x:Class="Example.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Example" xmlns:albert="http://www.albert.com" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="st1"> <Setter Property="Control.FontFamily" Value="宋体" ></Setter> <Setter Property="Control.FontSize" Value="33"></Setter> <Setter Property="Control.Background"> <Setter.Value> <ImageBrush TileMode="Tile"></ImageBrush> </Setter.Value> </Setter> <EventSetter Event="Button.MouseEnter " Handler="FrameworkElement_MouseDown"></EventSetter> </Style> </Window.Resources> <Grid> <Button Style="{StaticResource ResourceKey=st1}"></Button> </Grid> </Window>
MouseDown事件使用的是直接路由事件,这意味着他们不能在元素树中冒泡和隧道移动。在代码中会出现如下事件:
private void FrameworkElement_MouseEnter(object sender, MouseEventArgs e) { ((Button)sender).Content = "sadasd"; MessageBox.Show("22"); }
当前鼠标移动当前Button按钮上,则触发当前事件。
3、多层样式,样式的继承
我们使用baseOn属性创建一条完整的样式继承链。唯一的规则是,如果两次设置了同一个属性,最后的属性设置器会覆盖其他以前设置的定义。
<Window.Resources> <Style x:Key="st1"> <Setter Property="Control.FontFamily" Value="宋体" ></Setter> <Setter Property="Control.FontSize" Value="23"></Setter> <EventSetter Event="Button.MouseEnter" Handler="FrameworkElement_MouseEnter"></EventSetter> </Style> <Style x:Key="st2" BasedOn="{StaticResource st1}"> <Setter Property="Control.FontSize" Value="33"></Setter> </Style> </Window.Resources>
4、通过类型自动应用样式
前面主要应用了如何给具体控件应用样式,有没有一种方式,能够给特定类型的元素自动应用样式,在WPF中,这个工作非常简单,只需要设定TargetType属性,以指定合适的类型特定的样式。其基本示例如下:
<Style x:Key="st1" TargetType="Button"> <Setter Property="Control.FontFamily" Value="宋体" ></Setter> <Setter Property="Control.FontSize" Value="23"></Setter> <EventSetter Event="Button.MouseEnter" Handler="FrameworkElement_MouseEnter"></EventSetter> </Style>
5、简单触发器
触发器比较类似CSS中的伪类,但是比伪类功能更具体,能获取按钮上任意依赖属性,并且改变当前控件的样式,比如,我们想控件在获取交点的时候,显示33号字体,鼠标移开显示23号字体。则可以使用触发器。其基本示例如下:
<Window x:Class="Example.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Example" xmlns:albert="http://www.albert.com" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <Style x:Key="st1" TargetType="Button"> <Setter Property="Control.FontFamily" Value="宋体" ></Setter> <Setter Property="Control.FontSize" Value="23"></Setter> <EventSetter Event="Button.MouseEnter" Handler="FrameworkElement_MouseEnter"></EventSetter> </Style> <Style x:Key="st2" BasedOn="{StaticResource st1}"> <Style.Triggers> <Trigger Property="Control.IsFocused" Value="true"> <Setter Property="Control.FontSize" Value="33"></Setter> </Trigger> <Trigger Property="Control.IsFocused" Value="false"> <Setter Property="Control.FontSize" Value="23"></Setter> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel VerticalAlignment="Center"> <Button Style="{StaticResource ResourceKey=st1}" Content="111" ></Button> <Button Style="{StaticResource ResourceKey=st1}" Content="222"></Button> </StackPanel> </Window>
当前代码,会根据控件是否获取焦点,而显示不同大小的字体。
6、事件触发器
普通触发器,等待属性发生变化,而事件触发器等待特定的事件被引发。事件触发器要求用户提供一系列修改控件的动作,这些动作通常被用于动画中。