WPF中样式:类似于winform中控件的属性
<Grid>
<!-- Button属性 字体大小 字体颜色 内容 控件宽 高 -->
<Button FontSize="20" Foreground="Blue" Content="Hello" Width="100" Height="40"/>
</Grid>
效果如下:
如果要创建多个相似效果的按钮,就需要将该属性写多次,虽然也能达到相同的效果;但是费力。
<Grid>
<StackPanel>
<!-- Button属性 字体大小 字体颜色 内容 控件宽 高 -->
<Button FontSize="20" Foreground="Blue" Content="Hello" Width="100" Height="40"/>
<Button FontSize="20" Foreground="Blue" Content="Hello" Width="100" Height="40"/>
<Button FontSize="20" Foreground="Blue" Content="Hello" Width="100" Height="40"/>
</StackPanel>
</Grid>
效果如下:
因此,首先想到的是早轮子重复使用。需要通过Style。
创建样式的步骤:
- 在Window.Resources中创建样式
- 给每个样式声明一个键Key,一个样式的名称而已
- 给每个样式声明一个目标类型TargetType,例如Button
- 设置属性:(Button为例)
- 字体大小FontSize
- 背景颜色Background
- 字体颜色Foreground,边距Margin
- 水平位置HorizontalAlignment,垂直位置VerticalAlignment
样式是组织和重用以上的重要工具。不是使用重复的标记填充XAML,通过Styles创建一系列封装所有这些细节的样式。它也是模板(Template)、触发器(Trigger)的基础。
<Window.Resources>
<Style x:Key="defaultStyle" TargetType="Button">
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="40"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource defaultStyle}" Content="Hello"/>
<Button Style="{StaticResource defaultStyle}" Content="Hello"/>
<Button Style="{StaticResource defaultStyle}" Content="Hello"/>
</StackPanel>
</Grid>
效果如下:
查询Style源代码:
namespace System.Windows
{
//
// 摘要:
// 启用的属性、 资源和事件处理程序的一种类型的实例之间共享。
[ContentProperty("Setters")]
[DictionaryKeyProperty("TargetType")]
[Localizability(LocalizationCategory.Ignore)]
public class Style : DispatcherObject, INameScope, IAddChild, ISealable, IHaveResources, IQueryAmbient
{
//
// 摘要:
// 初始化 System.Windows.Style 类的新实例。
public Style();
//
// 摘要:
// 新实例初始化 System.Windows.Style 类,用于对指定 System.Type。
//
// 参数:
// targetType:
// 该样式将应用于哪个类型。
public Style(Type targetType);
//
// 摘要:
// 新实例初始化 System.Windows.Style 类,用于对指定 System.Type 并根据指定 System.Windows.Style。
//
// 参数:
// targetType:
// 该样式将应用于哪个类型。
//
// basedOn:
// 要基于此样式的样式。
public Style(Type targetType, Style basedOn);
//
// 摘要:
// 获取一个值,该值指示是否样式是只读的并且不能更改。
//
// 返回结果:
// true 如果样式密封的;,否则为 false。
public bool IsSealed { get; }
//
// 摘要:
// 获取或设置此样式所针对的类型。
//
// 返回结果:
// 此样式目标类型。
[Ambient]
[Localizability(LocalizationCategory.NeverLocalize)]
public Type TargetType { get; set; }
//
// 摘要:
// 获取或设置是当前样式的基础已定义的样式。
//
// 返回结果:
// 已定义的样式,其当前样式的基础。 默认值为 null。
[Ambient]
[DefaultValue(null)]
public Style BasedOn { get; set; }
//
// 摘要:
// 获取一套 System.Windows.TriggerBase 应用属性值的对象根据指定的条件。
//
// 返回结果:
// System.Windows.TriggerBase 对象的集合。 默认值为空集合。
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TriggerCollection Triggers { get; }
//
// 摘要:
// 获取一套 System.Windows.Setter 和 System.Windows.EventSetter 对象。
//
// 返回结果:
// 一套 System.Windows.Setter 和 System.Windows.EventSetter 对象。 默认值为空集合。
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public SetterBaseCollection Setters { get; }
//
// 摘要:
// 获取或设置此样式的作用域内的可用资源的集合。
//
// 返回结果:
// 可以使用此样式的作用域内的资源。
[Ambient]
public ResourceDictionary Resources { get; set; }
//
// 摘要:
// 返回此 System.Windows.Style 的哈希代码。
//
// 返回结果:
// 此 System.Windows.Style 的哈希代码。
public override int GetHashCode();
//
// 摘要:
// 在当前的名称范围中注册新的名称对象对。
//
// 参数:
// name:
// 要注册的名称。
//
// scopedElement:
// 要映射到指定的对象 name。
public void RegisterName(string name, object scopedElement);
//
// 摘要:
// 锁定此样式和所有工厂和触发器,使它们不能进行更改。
public void Seal();
//
// 摘要:
// 从名称范围中移除名称对象映射。
//
// 参数:
// name:
// 要删除的映射的名称。
public void UnregisterName(string name);
}
}
- TargetType:Style的作用类型,例如Button。
- BaseOn:继承已有的样式。
- TriggerCollection:触发器集合。
- SetterBaseCollection:属性集合。
- ResourceDictionary:资源字典,比如笔刷,样式。
样式的作用:样式可以包含多个属性(样式管理属性集合),并批量作用于对象(不用写过多重复代码),也可以用于继承。
<Window.Resources>
<Style TargetType="Button">
<Setter Property="FontSize" Value="25"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Content" Value="Button"/>
</Style>
</Window.Resources>
<Grid>
<UniformGrid Columns="3" Rows="3">
<Button />
<Button />
<Button />
<Button />
<Button />
<Button />
<Button />
<Button />
<Button />
</UniformGrid>
</Grid>
效果如下:
给样式起名字,并在作用对象中使用该样式:
<Window.Resources>
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="25"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Content" Value="Button"/>
</Style>
</Window.Resources>
<Grid>
<UniformGrid Columns="3" Rows="3">
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
<Button Style="{StaticResource ButtonStyle}"/>
</UniformGrid>
</Grid>
效果如下:
样式继承
<Window.Resources>
<Style x:Key="baseButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="Blue"/>
</Style>
<Style x:Key="defaultButtonStyle1" TargetType="Button" BasedOn="{StaticResource baseButtonStyle}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="40"/>
</Style>
<Style x:Key="defaultButtonStyle2" TargetType="Button" BasedOn="{StaticResource baseButtonStyle}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="50"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<!-- Button属性 字体大小 字体颜色 内容 控件宽 高 -->
<Button Style="{StaticResource defaultButtonStyle1}" Content="Hello"/>
<Button Style="{StaticResource defaultButtonStyle2}" Content="Hello"/>
<Button Style="{StaticResource defaultButtonStyle2}" Content="Hello"/>
</StackPanel>
</Grid>
效果如下:
控件模板ControlTemplate
视图->其他->文档大纲
右键按钮->编辑模板->编辑副本
产生按钮模板:
<Window.Resources>
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Content Presenter使得按钮可以承载很多内容。