你听我说-HandyControl调整样式色系

简介: 你听我说-HandyControl调整样式色系

问题场景

HandyControl中自带的色系想要自己自定义如何操作和处理?

加入个人自定义的色系资源,应该如何操作更符合HandyControl风格?

问题分析

每次选择演示Demo中的主题皮肤,能够对案例进行整理的样式色系调整,实际上就是每次都替换了一套对应的色系资源文件,由于资源中使用的是动态资源方式DynamicResource进行添加,并未更改对应的资源的键名称

HandyControl资源如下:

  • [色系]https://handyorg.gitee.io/handycontrol/basic_xaml/colors
  • [画刷]https://handyorg.gitee.io/handycontrol/basic_xaml/brushes/

案例换肤

默认

暗色

紫色

资源引用

以案例项目App.xaml作为系统资源入口,存在如下关系

App.xaml

<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
                        <ResourceDictionary Source="Resources/Themes/SkinDefault.xaml"/>
                    </ResourceDictionary.MergedDictionaries>
                </ResourceDictionary>
                <ResourceDictionary>
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
                        <ResourceDictionary Source="Resources/Themes/Theme.xaml"/>
                    </ResourceDictionary.MergedDictionaries>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
            ......省略无关项.......
        </ResourceDictionary>
    </Application.Resources>

图解关系

资源组成

主要分为Theme.xamlSkinXXX.xaml两类资源字典文件,属于HandyControl_SharedHandyControl库自带的相关色系和样式资源,属于本地案例HandyControlDemo_SharedTheme.xaml以及SkinXXX.xaml为类库样式的扩展和色系自定义,同时也是用户自定义样式,总之一句话就是UI库没有的,当前项目需要,就添加到本地

色系与皮肤组

每一个皮肤组,就是一套完整的运行项目皮肤,至少有一个Theme.xamlSkinXXX.xaml组成,其中,画刷间接性依赖不同SkinXXX.xaml中对应的ColorsXXX.xaml

解决方案

上图的主要目的是表明,色系作为资源,在保证是DynamicResource资源加载方式时,Key不变,替换掉对应资源内容值,就能够实现样式的改变,HandyControl库中的资源改不了,那控件自带的色系无法变更,本地资源可以变更,在保证Key值一致情况下,本地加载实际资源组,达到替换皮肤色系的目的

替换默认皮肤

HandyControl类库的基础教程中,默认使用的是SkinDefault.xaml的皮肤色系,如果要选择其他色系,可以通过修改App.xaml中的需要合并的资源

创建项目

本地创建一个案例项目名叫blog_hc_style,引用HandyControlNuget包,此处版本为3.2.0,基础配置操作请阅读官方文档[快速开始]https://handyorg.gitee.io/handycontrol/quick_start/

App.xaml

<Application x:Class="blog_hc_style.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:blog_hc_style"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
                    </ResourceDictionary.MergedDictionaries>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

MainWindow.xaml

<Window x:Class="blog_hc_style.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:blog_hc_style"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TabControl>
            <TabItem Header="测试01">
            </TabItem>
            <TabItem Header="测试02">
            </TabItem>
            <TabItem Header="测试03">
            </TabItem>
            <TabItem Header="测试04">
            </TabItem>
        </TabControl>
    </Grid>
</Window>

运行效果

修改资源

如果只是为了替换默认色系,可以直接替换App.xaml中上文提过的SkinXXX.xaml,即可

App.xaml,如下,将色系修改为HandyControl库中自带的Dark色系

<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <ResourceDictionary.MergedDictionaries>
                        <!--合并Dark为目标色系-->
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDark.xaml"/>
                        <!--替换原始色系-->
                        <!--<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>-->
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
                    </ResourceDictionary.MergedDictionaries>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

运行效果

自定义本地色系

自定义本地色系时,需要将源码Colors.xaml中的所有内容拷贝到本地项目内的资源样式中文件中,主要 目的是为了保持,色系和皮肤的结构的统一性,便于日后维护,自定义本地色系依旧是基于上述案例项目进行本地改造

调整色值

新建ColorsLocal.xaml以及SkinLocal.xamlColorsLocal.xaml用于存放本地颜色值,SkinLocal.xaml用于作为中间层进行字典合并,同时保证目录结构的统一性

复制HandyControl源码HandyControl_Shared中的Colors.xaml,每个颜色样式的的说明可查看[官方文档-颜色]https://handyorg.gitee.io/handycontrol/basic_xaml/colors/,依据用途调整对应的色值,以下是笔者自己调整之后的样式

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:system="clr-namespace:System;assembly=mscorlib">
    <Color x:Key="LightPrimaryColor">#8b7fb6</Color>
    <Color x:Key="PrimaryColor">#5d5386</Color>
    <Color x:Key="DarkPrimaryColor">#312a59</Color>
    <Color x:Key="LightDangerColor">#ff6b70</Color>
    <Color x:Key="DangerColor">#db3340</Color>
    <Color x:Key="DarkDangerColor">#db3340</Color>
    <Color x:Key="LightWarningColor">#ffe158</Color>
    <Color x:Key="WarningColor">#e9af20</Color>
    <Color x:Key="DarkWarningColor">#e9af20</Color>
    <Color x:Key="LightInfoColor">#60d4ea</Color>
    <Color x:Key="InfoColor">#00bcd4</Color>
    <Color x:Key="DarkInfoColor">#00bcd4</Color>
    <Color x:Key="LightSuccessColor">#64da73</Color>
    <Color x:Key="SuccessColor">#2db84d</Color>
    <Color x:Key="DarkSuccessColor">#2db84d</Color>
    <Color x:Key="PrimaryTextColor">#212121</Color>
    <Color x:Key="SecondaryTextColor">#757575</Color>
    <Color x:Key="ThirdlyTextColor">#bdbdbd</Color>
    <Color x:Key="ReverseTextColor">#212121</Color>
    <Color x:Key="TextIconColor">White</Color>
    <Color x:Key="BorderColor">#e0e0e0</Color>
    <Color x:Key="SecondaryBorderColor">#e0e0e0</Color>
    <Color x:Key="BackgroundColor">#f1f2f7</Color>
    <Color x:Key="RegionColor">#ffffff</Color>
    <Color x:Key="SecondaryRegionColor">#f9f9f9</Color>
    <Color x:Key="ThirdlyRegionColor">White</Color>
    <Color x:Key="TitleColor">#326cf3</Color>
    <Color x:Key="SecondaryTitleColor">#326cf3</Color>
    <Color x:Key="DefaultColor">#f9f9f9</Color>
    <Color x:Key="DarkDefaultColor">#2c304d</Color>
    <Color x:Key="AccentColor">#f8491e</Color>
    <Color x:Key="DarkAccentColor">#f8491e</Color>
    <Color x:Key="DarkMaskColor">#20000000</Color>
    <Color x:Key="DarkOpacityColor">#40000000</Color>
    <system:UInt32 x:Key="BlurGradientValue">0x99FFFFFF</system:UInt32>
    <Color x:Key="PinkColor">#e76c90</Color>
</ResourceDictionary>

SkinLocal.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/blog_hc_style;component/Resources/Themes/Basic/Colors/ColorsLocal.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary

替换色系资源

修改App.xaml中合并资源的SkinDark.xamlSkinLocal.xaml

<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <ResourceDictionary.MergedDictionaries>
                        <ResourceDictionary Source="pack://application:,,,/blog_hc_style;component/Resources/Themes/SkinLocal.xaml"/>
                        <!--合并Dark为目标色系-->
                        <!--<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDark.xaml"/>-->
                        <!--替换原始色系-->
                        <!--<ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>-->
                        <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
                    </ResourceDictionary.MergedDictionaries>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
 </Application.Resources>

运行效果

组合色值(非必要)

此操作为可选操作,为用户对现有控件画刷颜色进行整体重写时可用(比较简单粗暴的操作),画刷用途请查看[官方文档-画刷]https://handyorg.gitee.io/handycontrol/basic_xaml/brushes/,这样的破坏性修改,建议在不熟悉HandyControl情况下不要轻易应用的实际生产中,容易打乱HandyControl的内部色系布局

注意

不少资源并未包含在HandyControl.dll程序集中,如果小伙伴瞧得起对应案例的资源样式,可以考虑自己从案例中刨出去使用即可,私聊回复【hcstyle】获取本文对应案例

后续将继续构建HandyControl的相关系列,有相关想法,进行留言:【HandyControl



相关文章
|
C# 容器
WPF技术之HorizontalAlignment和VerticalAlignment
HorizontalAlignment和VerticalAlignment是用来确定控件在其父容器中的水平和垂直位置的属性。
1658 0
WPF技术之HorizontalAlignment和VerticalAlignment
|
机器学习/深度学习 传感器 人工智能
物联网常用协议:MQTT、CoAP、LwM2M、HTTP、LoRaWAN和NB-IoT
物联网常用协议:MQTT、CoAP、LwM2M、HTTP、LoRaWAN和NB-IoT
物联网常用协议:MQTT、CoAP、LwM2M、HTTP、LoRaWAN和NB-IoT
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
693 1
halcon联合c#、WPF学习笔记三(dispatcherTimer实时相机显示)
|
移动开发 JavaScript 前端开发
使用css 与 js 两种方式实现导航栏吸顶效果
使用css 与 js 两种方式实现导航栏吸顶效果
|
容器 C# Docker
WPF与容器技术的碰撞:手把手教你Docker化WPF应用,实现跨环境一致性的开发与部署
【8月更文挑战第31天】容器技术简化了软件开发、测试和部署流程,尤其对Windows Presentation Foundation(WPF)应用程序而言,利用Docker能显著提升其可移植性和可维护性。本文通过具体示例代码,详细介绍了如何将WPF应用Docker化的过程,包括创建Dockerfile及构建和运行Docker镜像的步骤。借助容器技术,WPF应用能在任何支持Docker的环境下一致运行,极大地提升了开发效率和部署灵活性。
670 1
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS前端技术趋势篇】前端框架(React/Vue/Angular)与HTML/CSS的结合使用
【4月更文挑战第30天】前端框架React、Vue和Angular助力UI开发,通过组件化、状态管理和虚拟DOM提升效率。这些框架与HTML/CSS结合,使用模板语法、样式管理及组件化思想。未来趋势包括框架简化、Web组件标准采用和CSS在框架中角色的演变。开发者需紧跟技术发展,掌握新工具,提升开发效能。
348 11
|
Java Shell Python
【经验分享】Typora 设置代码块的默认语言并设置为开机启动
在Typora中设置代码块默认语言为Java(或其他语言)的自动化方法。通过下载AHK(AutoHotkey)软件,创建一个.ahk脚本,设定`Ctrl+Shift+K`快捷键触发代码块并输入指定语言。将脚本改名为.ahk扩展名并运行,确保图标出现在任务栏。要实现开机启动,使用Win+R打开&quot;运行&quot;,输入shell:startup并粘贴.ahk文件到启动文件夹。
871 2
|
前端开发 C#
WPF技术之ContentControl 控件
ContentControl 是 WPF 中的一个常见控件,用于显示单个内容元素。它可以包含任意类型的内容,包括文本、图像、控件等。
2348 0
|
算法 C# UED
浅谈WPF之控件模板和数据模板
WPF不仅支持传统的Windows Forms编程的用户界面和用户体验设计,同时还推出了以模板为核心的新一代设计理念。在WPF中,通过引入模板,将数据和算法的“内容”和“形式”进行解耦。模板主要分为两大类:数据模板【Data Template】和控件模板【Control Template】。
480 8
|
XML C# 数据格式
WPF技术之DocumentViewer控件
WPF 的 DocumentViewer 是一个强大的控件,用于在应用程序中显示各种类型的文档,如 XPS(XML Paper Specification)、FlowDocument 和 FixedDocument 等。
2561 1