WPF中样式

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使得按钮可以承载很多内容。

相关推荐
猫霸4 小时前
WPF静态资源StaticResource和动态资源DynamicResource有什么区别,x:Static又是什么意思?
分布式·c#·.net·wpf
wqq10276 小时前
WPF 从Main()方法启动
wpf
明耀11 小时前
WPF ListBox双击事件
wpf
wqq102712 小时前
WPF 依赖注入启动的问题
wpf
wqq102716 小时前
WPF 使用 DI EF CORE SQLITE
sqlite·wpf
Marzlam2 天前
一文读懂WPF系列之MVVM
wpf
Marzlam2 天前
一文读懂WPF系列之依赖属性与附加属性
wpf
zxb11c2 天前
WPF 中的元素继承层次结构 ,以下是对图中内容的详细说明:
wpf
Zhen (Evan) Wang2 天前
Margin和Padding在WPF和CSS中的不同
css·wpf
Marzlam2 天前
一文读懂WPF布局
wpf