WPF中的Style(风格,样式)
1.统一样式设定
在WPF中我们可以使用Style来设置控件的某些属性值,并使该设置影响到指定范围内的所有该类控件或影响指定的某一控件,比如说我们想将窗口中的所有按钮都保持某一种风格,那么我们可以设置一个Style,而不必分别设置每个按钮的风格。
Style是作为一种资源被保存下来的。看下面的例子:
<Window.Resources> <Style TargetType="Button"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontFamily" Value="CourierNew"/> </Style> </Window.Resources>
在此处声明了一个Style,它被声明在Window.Resources中说明它的有效范围是当前窗体
TargetType="Button" 指示该Style的作用对象是Button类的实例,也就是说在当前窗体中的所有Button实例都将受到该Style的影响(除非某Button有明确地指明它所使用的是另外的Style)。
<Setter Property="Foreground" Value="Blue"/> 这里的Setter是一个设置器,用来设置该Style要对TargetType的那些属性或对象进行设置,我们这里设置的是Button的Foreground属性,将其值设置为Blue,同理,我们将Button的FontFamily属性设置为CourierNew
这样一来,在默认情况下,被加载到窗口中的所有Button对象都将受到这个Style的影响,从而文本变成统一的蓝色CourierNew字体。
你可以粘贴以下代码到XamlPad中查看效果:
<Window.Resources> <Style TargetType="Button"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontFamily" Value="CourierNew"/> </Style> </Window.Resources> <Grid ShowGridLines="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="50*"/> <ColumnDefinition Width="50*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="25*"/> <RowDefinition Height="25*"/> <RowDefinition Height="25*"/> </Grid.RowDefinitions> <Button Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="1">button1</Button> <Button Grid.Column="2" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1">button2</Button> </Grid>
此时窗体上的button控件都是统一样式。
2.单独样式设定
但是在实际中,需要对窗体上不同的button设置不同的样式,此时用上面的方法就无法实现,在定义style中需要对不同样式定义不同的名称
参考以下代码:我们为Style添加一个x:Key="ButtonStyle"指定Style名称
<Window.Resources> <Style TargetType="Button" x:Key="ButtonStyle"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontFamily" Value="CourierNew"/> </Style> </Window.Resources>
然后我们使用Button的Style属性来指定该Button所要使用的Style,而其他没有将我们声明的Style指定为其样式的按钮将不受到该Style的影响。
<Button Style="{StaticResource ButtonStyle}">styled button</Button>
这样就很好的解决了Style强制影响每个Button的问题,代码如下:
<Window.Resources> <Style TargetType="Button" x:Key="ButtonStyle"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontFamily" Value="CourierNew"/> </Style> </Window.Resources> <Grid ShowGridLines="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="50*"/> <ColumnDefinition Width="50*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="25*"/> <RowDefinition Height="25*"/> <RowDefinition Height="25*"/> </Grid.RowDefinitions> <Button Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="1">normal button</Button> <Button Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1" Style="{StaticResource ButtonStyle}">styled button1</Button> <Button Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="2" Grid.RowSpan="1" Style="{StaticResource ButtonStyle}">styled button2</Button> </Grid>
3.触发器
<Window.Resources> <Style TargetType="Button" x:Key="ButtonStyle"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontFamily" Value="CourierNew"/> </Style> <Style TargetType="Button" x:Key="TriggerButtonStyle" BasedOn="{StaticResource ButtonStyle}"> <Style.Triggers> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources>
代码中样式TriggerButtonStyle,它“继承”于ButtonStyle,那么TriggerButtonStyle将会从ButtonStyle那里得到蓝色CourierNew文本的性质。另外还定义了Trigger来响应鼠标按下, <Trigger Property="IsPressed" Value="True"> 表示当Button的IsPressed属性值变为True的时候,将做如下设置<Setter Property="Foreground" Value="Red"/>,即将Button的Foreground属性设置为Red。这里有一个隐含的意思是:当Button的IsPressed属性值变为False的时候,Foreground属性将恢复原值。
全部代码如下:
<Window.Resources> <Style TargetType="Button" x:Key="ButtonStyle"> <Setter Property="Foreground" Value="Blue"/> <Setter Property="FontFamily" Value="CourierNew"/> </Style> <Style TargetType="Button" x:Key="TriggerButtonStyle" BasedOn="{StaticResource ButtonStyle}"> <Style.Triggers> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid ShowGridLines="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="50*"/> <ColumnDefinition Width="50*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="25*"/> <RowDefinition Height="25*"/> <RowDefinition Height="25*"/> </Grid.RowDefinitions> <Button Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="0" Grid.RowSpan="1">normal button</Button> <Button Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1" Style="{StaticResource ButtonStyle}">styled button</Button> <Button Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="2" Grid.RowSpan="1" Style="{StaticResource TriggerButtonStyle}">trigger button
</Button> </Grid>
效果图如下,trigger button默认具有和styled button同样的属性,当单击该按钮时,字体变成红色,触发trigger
一个应用程序中,某个窗口需要使用样式,但是样式非常多,写在一个窗口中代码分类不方便。最好写在专门的xaml文件中,然后引用到窗口中,就像HTML引用外部css文件一样。目的就在于可以实现多个项目之间的共享资源,资源字典只是一个简单的XAML文档,该文档除了存储希望使用的资源之外,不做任何其它的事情。
<?xml version="1.0" encoding="utf-8"?> <!--This file is auto generated by XDraw.--> <!--Do not modify this file directly, or your changes will be overwritten.--> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <LinearGradientBrush x:Key="FadeBrush"> <GradientStop Color="Red" Offset="0"/> <GradientStop Color="Gray" Offset="1"/> </LinearGradientBrush> </ResourceDictionary>
③设置资源文件编译方式为Page
④ 集成资源
要是用资源字典,首先要将资源字典集成到应用程序的某些资源集合中。一般的做法都是在app.xaml文件中进行集成。app.xaml文件代码如下:
<Application x:Class="WpfResourceDictionary.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources/MyStyle.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
⑤使用资源
集成之后就可以在当前的工程中使用这些资源了。使用方法如下,在窗体中引用
<Grid Height="304" Width="374"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Button Margin="121,30,107,230" Grid.Row="2" Background="{StaticResource FadeBrush}"> </Button> </Grid>
窗体中无需定义Style,可进行引用
⑥查看效果