WPF 全局样式资源管理

在WPF通常我们习惯于把样式直接写在控件属性上,例如:

<TextBox
    x:Name="pluginPathTxt"
    Margin="0,0,0,0" 
    Background="White" 
    Cursor="IBeam"
    TextWrapping="Wrap" 
    AcceptsReturn="True" 
    VerticalScrollBarVisibility="Visible"
    />

这样写非常直观,但是如果相同的控件很多,就要重复写很多样式代码,不仅代码冗余,而且不易维护。或者后续可能需要统一调整某个控件的样式,这时候改动起来可就不是那么容易了。因此我们要将相同的控件样式维护在一起。

新建资源文件

在项目中右键新增资源文件

然后将全局样式编写在资源文件中

全局资源样式文件必须被引用才可以生效,在项目的 App.xaml 中引用资源文件

<Application x:Class="Chimes.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Chimes"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!--引入自定义全局资源字典-->
                <ResourceDictionary Source="pack://application:,,,/xx类库名;component/GlobalStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

因为我这里是在单独类库加的资源文件,因此路径增加了类库名。如果是在当前项目中增加,则直接引用即可

<ResourceDictionary Source="pack://application:,,,/Resources/GlobalStyles.xaml" />
注:可以将所有Style样式放在同一个资源文件中,也可以拆分成多个资源文件分别引用

如果不想增加新的资源文件,我们把Style样式都放在 App.xaml 文件中也可以达到同样的效果,例如:

<Application x:Class="Chimes.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Chimes"
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!--引入自定义全局资源字典-->
                <ResourceDictionary Source="pack://application:,,,/Chimes.Plugin;component/GlobalStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <!--全局按钮样式-->
            <Style TargetType="{x:Type Button}">
                <Setter Property="FontFamily" Value="Microsoft YaHei" />
                ....
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

样式的定义

在全局样式资源的编写中,一般有两种定义方式,一种是全局资源类型,另一个种是指定key的资源类型。

全局资源定义

全局的资源文件会在所有指定类型的控件生效。例如,在资源文件中指定了项目中所有Button类型都适用样式规则

<!--全局按钮样式-->
<Style TargetType="{x:Type Button}">
    <Setter Property="FontFamily" Value="Microsoft YaHei" />
</Style>

编写控件代码时,我们只需要增加控件即可生效

<Button Click="Btn_Copy" >复制</Button>

指定key的资源定义

指定key的资源文件则必须在空间上绑定资源key才会生效。例如,在资源文件中指定了项目中绑定了 key=gridSplitterVerticalStyle 的控件才使用样式规则

<!--垂直分隔符-->
<Style x:Key="gridSplitterVerticalStyle" TargetType="{x:Type GridSplitter}">
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalAlignment" Value="Right"/>
    <Setter Property="Background" Value="#FFBAE3FF"/>
    <Setter Property="Width" Value="3"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Width" Value="4"/>
            <Setter Property="Background" Value="#80ccff"/>
        </Trigger>
    </Style.Triggers>
</Style>

编写控件代码时,我们要绑定该key才会生效,不绑定的控件不会适用样式

<GridSplitter Grid.Column="1" Style="{StaticResource gridSplitterVerticalStyle}"/>

混合定义

我们也可以将指定key的样式应用到全局中,这种使用方式在某些场景非常实用。比如我们使用key定义了多个控件的样式,然后指定其中一种为全局样式,在编写控件时,默认为指定全局的样式,在某些地方可以绑定需要的key来采用特殊的样式覆盖全局。

<!--垂直分隔符-->
<Style x:Key="gridSplitterVerticalStyle" TargetType="{x:Type GridSplitter}">
    <Setter Property="VerticalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalAlignment" Value="Right"/>
    <Setter Property="Background" Value="#FFBAE3FF"/>
    <Setter Property="Width" Value="3"/>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Width" Value="4"/>
            <Setter Property="Background" Value="#80ccff"/>
        </Trigger>
    </Style.Triggers>
</Style>

<Style BasedOn="{StaticResource gridSplitterVerticalStyle}" TargetType="{x:Type GridSplitter}" />
posted @ 2023-07-29 15:47  7tiny  阅读(427)  评论(0编辑  收藏  举报