WPF—Style样式
样式——就是一种将一组属性值应用到多个元素的便捷方法。
样式的类型叫Style,继承于DispatcherObject,关键属性包括:
-
TargetType:指定样式适用的控件类型(如 Button) -
BasedOn:实现样式继承 -
Triggers:触发器集合(满足条件时动态修改样式) -
Setters:属性设置项集合(存储控件属性的键值对) -
Resources:资源字典(存放可复用的样式 / 资源)
一、Style写法
1、写在控件内部
样式只对该控件有效
<!--控件内部样式: 样式只对该控件有效 -->
<Button Content="按钮1"><Button.Style><Style TargetType="Button"><Setter Property="Background" Value="Green"/><Setter Property="Foreground" Value="White"/><Setter Property="FontSize" Value="20"/><Setter Property="Width" Value="100"/><Setter Property="Height" Value="50"/><Setter Property="Margin" Value="5" /></Style></Button.Style>
</Button>
效果

2、写在窗体文件
对当前窗体有效
2.1、不指定Key的Style
<!--窗体资源-->
<Window.Resources><!-- 根据类型匹配, 适应所有Button--><Style TargetType="Button"><Setter Property="Background" Value="Green"/><Setter Property="Foreground" Value="White"/><Setter Property="FontSize" Value="20"/><Setter Property="Width" Value="100"/><Setter Property="Height" Value="50"/><Setter Property="Margin" Value="5"/></Style>
</Window.Resources>
<Button Content="按钮1" Style="{StaticResource {x:Type Button}}">
</Button>
效果

2.2、指定key的Style
<Window.Resources><!--指定key的Style--><Style TargetType="Button" x:Key="RedButtonStyle"><Setter Property="Background" Value="Red"/><Setter Property="Foreground" Value="White"/><Setter Property="FontSize" Value="20"/><Setter Property="Width" Value="100"/><Setter Property="Height" Value="50"/><Setter Property="Margin" Value="5"/></Style>
</Window.Resources>
<Grid><StackPanel Orientation="Horizontal"><Button Content="按钮1"></Button><Button Content="按钮2" Style="{StaticResource RedButtonStyle}"></Button></StackPanel>
</Grid>
效果

3、样式继承(BasedOn)
样式支持 “基样式 + 扩展样式” 的继承模式,基样式定义通用属性,扩展样式仅覆盖差异化属性,减少重复代码。
<!--窗体资源-->
<Window.Resources><Style TargetType="Button" x:Key="BaseButtonStyle"><Setter Property="Foreground" Value="White"/><Setter Property="FontSize" Value="20"/><Setter Property="Width" Value="100"/><Setter Property="Height" Value="50"/><Setter Property="Margin" Value="5"/></Style><!--指定key的Style--><Style TargetType="Button" x:Key="RedButtonStyle" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Background" Value="SkyBlue"/></Style>
</Window.Resources>
<Grid><StackPanel Orientation="Horizontal"><Button Content="按钮1"></Button><Button Content="按钮2" Style="{StaticResource RedButtonStyle}"></Button></StackPanel>
</Grid>
效果

可以发现,为什么第一个按钮没有使用基本样式?因为 带 x:Key 的样式,不会自动应用到控件上
WPF 样式的两条铁律
-
只有
TargetType,没有x:Key,✅ 会自动应用到页面上所有同类型控件(所有Button自动生效)。 -
既有
TargetType,又有x:Key,❌ 不会自动应用,必须手动写Style="{StaticResource Key}"才会生效。
4、写在字典资源文件中
在整个项目的窗体有效
第一步、创建资源字典

第二步、把Style写在资源字典文件中(笔刷、模板都可以作为一种资源写在资源字典文件中)
<!--画笔 --><SolidColorBrush x:Key="ButtonBackground" Color="Blue"/><SolidColorBrush x:Key="ButtonForeground" Color="White"/><Style TargetType="Button" x:Key="BaseButtonStyle"><Setter Property="Foreground" Value="{StaticResource ButtonForeground}"/><Setter Property="FontSize" Value="20"/><Setter Property="Width" Value="100"/><Setter Property="Height" Value="50"/><Setter Property="Margin" Value="5"/></Style><!--指定key的Style--><Style TargetType="Button" x:Key="RedButtonStyle" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Background" Value="Red"/></Style><Style TargetType="Button" x:Key="GreenButtonStyle" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Background" Value="Green"/></Style>
如图:

第三步、在App.xaml文件中的 Application.Resources 中添加资源字典文件
<Application.Resources><!--创建一个ResourceDictionary对象--><ResourceDictionary><Style x:Key="TextBoxStyle" TargetType="TextBox"><Setter Property="Width" Value="200"/></Style><!--包含其他资源字典,使用MergedDictionaries属性添加 --><ResourceDictionary.MergedDictionaries><!--Source: 字典资源文件相对路径--><ResourceDictionary Source="/Dictionary1.xaml"></ResourceDictionary><!--其他的字典资源文件--></ResourceDictionary.MergedDictionaries></ResourceDictionary>
</Application.Resources>
如图:

第四步、直接使用
<Grid><StackPanel Orientation="Horizontal"><Button Content="按钮1" Style="{StaticResource BaseButtonStyle}"></Button><Button Content="按钮2" Style="{StaticResource GreenButtonStyle}"></Button><Button Content="按钮3" Style="{StaticResource RedButtonStyle}"></Button></StackPanel>
</Grid>
效果

二、Style触发器(Trigger)
Trigger触发器的四个属性:
-
Property:监听哪个属性(必须依赖属性) -
Value:属性等于什么值时触发 -
Setters:触发后修改哪些属性 -
SourceName:监听哪个控件的属性(默认自己)
需要注意的是:Trigger触发器的条件应该是当前控件拥有的属性名称
使用
在样式中添加:
<Style TargetType="Button" x:Key="GreenButtonStyle" BasedOn="{StaticResource BaseButtonStyle}"><Setter Property="Background" Value="Green"/><Style.Triggers><!--使用触发器,实现鼠标移入时样式--><Trigger Property="IsMouseOver" Value="True"><!--设置鼠标移入时, 样式属性--><Setter Property="Background" Value="Orange"/><Setter Property="Foreground" Value="Red"/><Setter Property="Width" Value="200"/><Setter Property="Height" Value="100"/><Setter Property="FontSize" Value="30"/></Trigger></Style.Triggers></Style>
如图:

效果

可以发现,我们虽然增加了鼠标移入设置背景颜色,但是为什么背景颜色为什么没有改变呢?因为Button 的外观不是由 Background 属性直接渲染的,而是由 ControlTemplate(控件模板)画出来的!
