WPF 實現更換主題色

?WPF 實現更換主題色

WPF 使用 WPFDevelopers.Minimal 如何更換主題色

作者:WPFDevelopersOrg

原文鏈接: ? ?https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal

  • 框架使用大于等于.NET40

  • Visual Studio 2022;

  • 項目使用 MIT 開源許可協議;

  • Nuget Install-Package WPFDevelopers.Minimal 3.2.6-preview

  • 定義一個公共顏色資源文件,所有控件都動態資源引用DynamicResource顏色的Key,然后這樣修改一個資源文件的Key ?SolidColorBrushColor顏色值就可以實現更換主題色;

  • 此篇主要是定義了多個公共顏色資源文件如下,選擇不同的資源文件進行更換App.xaml的資源字典實現更換主題色;

    • Application.Current.Resources.MergedDictionaries.Remove(Blue) 字典尋找Blue,然后移除Application.Current.Resources.MergedDictionaries.Add(Green); 就完成更換主題色;

    • 創建 Light.Blue

    • 創建 Light.Green

    • 創建 Light.Orange

    • 創建 Light.Pink

    • 創建 Light.Purple

    • 創建 Light.Purple7bd5469f7ef23542f8a877422422679a.png

  • 使用 WPFDevelopers.Minimal 如何更換主題色Nuget包大于等于3.2.3如下;

  • 新增主題色如下;

    • 新建資源文件Light.Carmine.xaml如下,自己更換顏色值即可;

<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"?po:Freeze="True"><!--Default顏色--><Color?x:Key="DefaultBorderBrushColor"?po:Freeze="True">#CD7474</Color><SolidColorBrush?x:Key="DefaultBorderBrushSolidColorBrush"?Color="{StaticResource?DefaultBorderBrushColor}"?po:Freeze="True"></SolidColorBrush><Color?x:Key="DefaultBackgroundColor"?po:Freeze="True">#CFA0A0</Color><SolidColorBrush?x:Key="DefaultBackgroundSolidColorBrush"?Color="{StaticResource?DefaultBackgroundColor}"?po:Freeze="True"></SolidColorBrush><Color?x:Key="DefaultBackgroundPressedColor"?po:Freeze="True">#B70404</Color><SolidColorBrush?x:Key="DefaultBackgroundPressedSolidColorBrush"?Color="{StaticResource?DefaultBackgroundPressedColor}"?po:Freeze="True"></SolidColorBrush><!--Primary顏色--><Color?x:Key="PrimaryNormalColor"?po:Freeze="True">#B31B1B</Color><SolidColorBrush?x:Key="PrimaryNormalSolidColorBrush"?Color="{StaticResource?PrimaryNormalColor}"?po:Freeze="True"></SolidColorBrush><SolidColorBrush?x:Key="WindowBorderBrushSolidColorBrush"?Color="{StaticResource?PrimaryNormalColor}"?po:Freeze="True"></SolidColorBrush><Color?x:Key="PrimaryMouseOverColor"?po:Freeze="True">#BB5F5F</Color><SolidColorBrush?x:Key="PrimaryMouseOverSolidColorBrush"?Color="{StaticResource?PrimaryMouseOverColor}"?po:Freeze="True"></SolidColorBrush><Color?x:Key="PrimaryPressedColor"?po:Freeze="True">#B70404</Color><SolidColorBrush?x:Key="PrimaryPressedSolidColorBrush"?Color="{StaticResource?PrimaryPressedColor}"?po:Freeze="True"></SolidColorBrush></ResourceDictionary>
  • 1)把上面新增的資源添加App.xaml中即可;

<Application?x:Class="WPFDevelopers.Minimal.Sample.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"StartupUri="ExampleViews\MainView.xaml"?ShutdownMode="OnMainWindowClose"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary?Source="pack://application:,,,/WPFDevelopers.Minimal.Sample.Net40;component/Light.Carmine.xaml"/><!--需要注意ws:Resources?必須再配色主題后,Theme="Dark"?為黑色皮膚?--><ws:Resources?Theme="Light"/><ResourceDictionary?Source="pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Theme.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>
</Application>
  • 2)或者把資源添加到ThemesCollection集合中;

if?(ThemesCollection?!=?null)ThemesCollection.Add(new?ThemeModel{Color?=?"#B31B1B",ResourcePath?="pack://application:,,,/WPFDevelopers.Minimal.Sample.Net40;component/Light.Carmine.xaml"});
  • 重啟應用效果如下;

1f717d599146a557f9586dcdd5aab94d.pngbf5310209d44c6fe91bba761385476ff.png

1)ThemeControl.cs代碼如下;

using?System;
using?System.Collections.Generic;
using?System.Collections.ObjectModel;
using?System.Collections.Specialized;
using?System.ComponentModel;
using?System.Linq;
using?System.Windows;
using?System.Windows.Controls;
using?WPFDevelopers.Minimal.Helpers;
using?WPFDevelopers.Minimal.Models;namespace?WPFDevelopers.Minimal.Controls
{public?class?ThemeControl?:?Control{public?static?readonly?DependencyProperty?ItemsSourceProperty?=DependencyProperty.Register("ItemsSource",?typeof(ObservableCollection<ThemeModel>),?typeof(ThemeControl),new?PropertyMetadata(null));static?ThemeControl(){DefaultStyleKeyProperty.OverrideMetadata(typeof(ThemeControl),new?FrameworkPropertyMetadata(typeof(ThemeControl)));}public?ObservableCollection<ThemeModel>?ItemsSource{get?=>?(ObservableCollection<ThemeModel>)GetValue(ItemsSourceProperty);set?=>?SetValue(ItemsSourceProperty,?value);}public?override?void?OnApplyTemplate(){base.OnApplyTemplate();ItemsSource?=?new?ObservableCollection<ThemeModel>();ItemsSource.Add(new?ThemeModel{Color?=?"#409EFF",ResourcePath?=?"pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Light.Blue.xaml"});ItemsSource.Add(new?ThemeModel{Color?=?"#FF033E",ResourcePath?=?"pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Light.Red.xaml"});ItemsSource.Add(new?ThemeModel{Color?=?"#A21BFC",ResourcePath?=?"pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Light.Purple.xaml"});ItemsSource.Add(new?ThemeModel{Color?=?"#FE9426",ResourcePath?=?"pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Light.Orange.xaml"});ItemsSource.Add(new?ThemeModel{Color?=?"#00B050",ResourcePath?=?"pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Light.Green.xaml"});ItemsSource.Add(new?ThemeModel{Color?=?"#FF007F",ResourcePath?=?"pack://application:,,,/WPFDevelopers.Minimal;component/Themes/Light.Pink.xaml"});if?(ThemeCache.ThemesDictCache.Count?>?0)foreach?(var?item?in?ThemeCache.ThemesDictCache)if?(ItemsSource.Any(x?=>?x.Color?!=?item.Key))ItemsSource.Add(item.Value);SelectChecked();ItemsSource.CollectionChanged?+=?ItemsSource_CollectionChanged;foreach?(var?theme?in?ItemsSource)theme.PropertyChanged?+=?Theme_PropertyChanged;}private?void?SelectChecked(){var?existsTheme?=?ItemsSource.FirstOrDefault(y?=>Application.Current.Resources.MergedDictionaries.ToList().Exists(j?=>j.Source?!=?null?&&?y.ResourcePath.Contains(j.Source.AbsoluteUri)));if?(existsTheme?!=?null)existsTheme.IsChecked?=?true;}private?void?ItemsSource_CollectionChanged(object?sender,?NotifyCollectionChangedEventArgs?e){switch?(e.Action){case?NotifyCollectionChangedAction.Add:foreach?(ThemeModel?item?in?e.NewItems){if?(!ThemeCache.ThemesDictCache.ContainsKey(item.Color))ThemeCache.ThemesDictCache.Add(item.Color,?item);item.PropertyChanged?+=?Theme_PropertyChanged;SelectChecked();if?(!item.IsChecked)?return;ReviseTheme(item);}break;case?NotifyCollectionChangedAction.Remove:foreach?(ThemeModel?item?in?e.NewItems)if?(ThemeCache.ThemesDictCache.ContainsKey(item.Color))ThemeCache.ThemesDictCache.Remove(item.Color);break;case?NotifyCollectionChangedAction.Replace:break;case?NotifyCollectionChangedAction.Move:break;case?NotifyCollectionChangedAction.Reset:break;}}private?void?Theme_PropertyChanged(object?sender,?PropertyChangedEventArgs?e){if?(e.PropertyName?==?nameof(ThemeModel.IsChecked)){var?theme?=?sender?as?ThemeModel;if?(!theme.IsChecked)?return;ReviseTheme(theme);}}private?void?ReviseTheme(ThemeModel?theme){if?(theme?==?null)?return;var?old?=?ItemsSource.FirstOrDefault(x?=>?x.IsChecked?&&?x.Color?!=?theme.Color);if?(old?!=?null){ItemsSource.Where(y?=>?!y.Color.Equals(theme.Color)?&&?y.IsChecked).ToList().ForEach(h?=>?h.IsChecked?=?false);var?existingResourceDictionary?=Application.Current.Resources.MergedDictionaries.FirstOrDefault(x?=>x.Source?!=?null?&&?x.Source.Equals(old.ResourcePath));if?(existingResourceDictionary?!=?null)Application.Current.Resources.MergedDictionaries.Remove(existingResourceDictionary);var?newResource?=Application.Current.Resources.MergedDictionaries.FirstOrDefault(x?=>x.Source?!=?null?&&?x.Source.Equals(theme.ResourcePath));if?(newResource?!=?null)?return;var?newResourceDictionary?=?new?ResourceDictionary?{?Source?=?new?Uri(theme.ResourcePath)?};Application.Current.Resources.MergedDictionaries.Insert(0,?newResourceDictionary);ControlHelper.ThemeRefresh();}}}public?class?ThemeCache{public?static?Dictionary<string,?ThemeModel>?ThemesDictCache?=?new?Dictionary<string,?ThemeModel>();}
}

2)Styles.ThemeControl.xaml代碼如下;

<ResourceDictionary?xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"xmlns:wpfsc="clr-namespace:WPFDevelopers.Minimal.Controls"xmlns:model="clr-namespace:WPFDevelopers.Minimal.Models"><ResourceDictionary.MergedDictionaries><ResourceDictionary?Source="../Themes/Basic/ControlBasic.xaml"/><ResourceDictionary?Source="../Themes/Basic/Animations.xaml"/></ResourceDictionary.MergedDictionaries><Style?TargetType="{x:Type?wpfsc:ThemeControl}"><Setter?Property="Template"><Setter.Value><ControlTemplate?TargetType="{x:Type?wpfsc:ThemeControl}"><ItemsControl?ItemsSource="{Binding?ItemsSource,RelativeSource={RelativeSource?AncestorType=wpfsc:ThemeControl}}"><ItemsControl.ItemTemplate><DataTemplate><RadioButton?Height="40"?Width="40"?Margin="4,0"Cursor="Hand"?IsChecked="{Binding?IsChecked}"><RadioButton.Style><Style?TargetType="{x:Type?RadioButton}"><Setter?Property="Template"><Setter.Value><ControlTemplate?TargetType="{x:Type?RadioButton}"><Border?x:Name="PART_Border"Padding="2"?BorderThickness="0"BorderBrush="{Binding?Color}"><Grid?Background="{x:Null}"><Rectangle?x:Name="PART_Rectangle"?Fill="{Binding?Color}"/><Path?Data="{StaticResource?PathCheckMark}"Stretch="Fill"?Fill="{DynamicResource?BackgroundSolidColorBrush}"VerticalAlignment="Bottom"HorizontalAlignment="Right"Height="10"?Width="12"Margin="0,0,4,4"Visibility="{Binding?IsChecked,Converter={StaticResource?bool2VisibilityConverter}}"/></Grid></Border><ControlTemplate.Triggers><Trigger?Property="IsMouseOver"?Value="True"><Setter?Property="Opacity"?Value=".8"?TargetName="PART_Rectangle"/><Setter?Property="BorderThickness"?Value="1"?TargetName="PART_Border"/></Trigger><Trigger?Property="IsChecked"?Value="True"><Setter?Property="BorderThickness"?Value="1"?TargetName="PART_Border"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style></RadioButton.Style></RadioButton></DataTemplate></ItemsControl.ItemTemplate><ItemsControl.ItemsPanel><ItemsPanelTemplate><WrapPanel/></ItemsPanelTemplate></ItemsControl.ItemsPanel></ItemsControl></ControlTemplate></Setter.Value></Setter></Style>
</ResourceDictionary>

3)ThemeControlExample.xaml代碼如下;

<!--命名空間-->xmlns:ws="https://github.com/WPFDevelopersOrg.WPFDevelopers.Minimal"<TextBlock?Text="Theme"?FontSize="20"?Margin="0,20,0,0"/><ws:ThemeControl?Margin="0,10"?ItemsSource="{Binding?ThemesCollection,RelativeSource={RelativeSource?AncestorType=local:MainView},Mode=OneWayToSource}"/>

ThemeControl|Github[1]
ThemeControl|碼云[2]
Styles.ThemeControl.xaml|Github[3]
Styles.ThemeControl.xaml|碼云[4]

參考資料

[1]

ThemeControl|Github: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal/blob/main/src/WPFDevelopers.Minimal/WPFDevelopers.Minimal.Shared/Controls/ThemeControl.cs

[2]

ThemeControl|碼云: https://gitee.com/WPFDevelopersOrg/WPFDevelopers.Minimal/blob/main/src/WPFDevelopers.Minimal/WPFDevelopers.Minimal.Shared/Controls/ThemeControl.cs

[3]

Styles.ThemeControl.xaml|Github: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal/blob/main/src/WPFDevelopers.Minimal/WPFDevelopers.Minimal.Shared/Styles/Styles.ThemeControl.xaml

[4]

Styles.ThemeControl.xaml|碼云: https://gitee.com/WPFDevelopersOrg/WPFDevelopers.Minimal/blob/main/src/WPFDevelopers.Minimal/WPFDevelopers.Minimal.Shared/Styles/Styles.ThemeControl.xaml

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/283896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/283896.shtml
英文地址,請注明出處:http://en.pswp.cn/news/283896.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue3與vue2的區別

先來說說當下市場開發使用的問題&#xff0c;目前2021年使用vue3開發的企業還是少&#xff0c;基本上都還是以vue2的形式進行開發&#xff0c;vue3的開發模式跟react很像&#xff0c;這時候有人就會想那我學vue3有用么&#xff0c;淦&#xff0c;他喵的&#xff0c;先別激動&am…

Spring Data REST API集成Springfox、Swagger

原文: Documenting a Spring Data REST API with Springfox and Swagger 使用Spring Date REST&#xff0c;你可以迅速為Spring Date repositories的創建REST API&#xff0c;并提供CRUD和更多功能。然而&#xff0c;在嚴謹的API開發過成功&#xff0c;您還希望擁有自動生成的最…

【系統設計】S3 對象存儲

在本文中&#xff0c;我們設計了一個類似于 Amazon Simple Storage Service (S3) 的對象存儲服務。S3 是 Amazon Web Services (AWS) 提供的一項服務&#xff0c; 它通過基于 RESTful API 的接口提供對象存儲。根據亞馬遜的報告&#xff0c;到 2021 年&#xff0c;有超過 100 萬…

轉: telnet命令學習

1.每天一個linux命令&#xff08;58&#xff09;&#xff1a;telnet命令 轉自&#xff1a; http://www.cnblogs.com/peida/archive/2013/03/13/2956992.html telnet命令通常用來遠程登錄。telnet程序是基于TELNET協議的遠程登錄客戶端程序。Telnet協議是TCP/IP協議族中的一員&a…

禪道、碼云、coding、redmine、jira、teambition幾大敏捷開發項目管理系統試用對比體驗

作為一個軟件公司的管理人員&#xff0c;在項目和人員多起來后&#xff0c;就需要通過系統來對項目和人員進行管理。 我們是典型的軟件外包公司&#xff0c;專為客戶定制軟件&#xff0c;所以我們的業務都是項目型的。因此&#xff0c;在管理模式上&#xff0c;我們就要用所謂…

Dubbo中的SPI機制

Dubbo中的SPI機制 概述 Service Provider Interface 即 SPI&#xff0c;是JDK內置的一種服務提供發現機制&#xff0c;可以用來啟用框架擴展和替換組件。可以讓不同的廠商針對統一接口編寫不同的實現 SPI實際上是“接口策略模式配置文件”實現的動態加載機制。在系統設計中&…

JWT:擁有我,即擁有權力

Hi&#xff0c;這里是桑小榆。上篇文章中&#xff0c;我們一起探討了 OAuth 協議的原理以及授權認證流程&#xff0c;本次我們一起探討 jwt 令牌作為授權協議的傳輸介質。OAuth協議規范了幾個參與角色的授權標準&#xff0c;安全可控的授予第三方應用&#xff0c;第三方應用獲取…

雙十一到來之前,阿里AI設計師“魯班”1天能做4000萬張海報

相比較去年&#xff0c;“魯班”的設計技藝有所提升。 人工智能很大程度上便利了我們的生活&#xff0c;現在他們甚至還能取代了一些設計師的工作&#xff0c;在雙十一正式到來之前&#xff0c;淘寶的宣傳已經鋪天蓋地&#xff0c;然而很多人都沒想到&#xff0c;我們打開淘寶…

Appium移動自動化測試之獲取appPackage和appActivity

方法一&#xff1a;直接打開Appium,點擊左上角機器人圖標 選擇apk所在位置&#xff0c;如圖所示&#xff0c;這里以ContactManager.apk為例 方法二&#xff1a;利用dex2jar和jd-gui這兩個工具反編譯apk文件 這里仍以ContactManager.apk為例 (1)重命名ContactManager.apk為Conta…

CAD轉WPF: 關于CAD圖紙文件轉換為WPF矢量代碼文件(xaml文件)的技巧

前言&#xff1a;下面的文章&#xff0c;我將會以幾個很簡單的步驟&#xff0c;來演示一下通過CAD圖紙轉換為XAML代碼文件的方法&#xff0c;供大佬們參考。一、為了演示一個簡單的操作&#xff0c;我此處先打開一個空白的CAD&#xff0c;等下用來進行繪制點內容使用。二、自定…

python之新式類與經典類

經典類與新式類經典類:P 或 P()--深度查找&#xff0c;向上查父節點新式類 :P(object)---廣度查找&#xff0c;繼承object&#xff0c;新式類的方法較多轉載于:https://www.cnblogs.com/zyy98877/p/8574983.html

Flowportal-BPM——環境配置

環境配置&#xff1a; 一、控制面板→程序和功能→打開或不關閉Window功能→選擇選項 二、控制面板→管理工具→Internet信息服務&#xff08;IIS&#xff09;管理器→左側第一個→ISAPI和CGI限制→全部選為【允許】 三、控制面板→管理工具→Internet信息服務&#xff08;IIS&…

一篇文章帶你搞懂什么是DevOps?

DevOps DevOps 它的英文發音是 /de’v?ps/&#xff0c;類似于“迪沃普斯”&#xff0c;一詞本身是對于 development 以及 operation 兩個詞的混合&#xff0c;其目的在于縮短系統開發的生命周期&#xff0c;在這過程中發布特性、修復bug以及更新均被緊密的結合。 簡化的含義為…

iOS 時間戳的轉換

在開發iOS程序時&#xff0c;有時候需要將時間格式調整成自己希望的格式&#xff0c;這個時候我們可以用NSDateFormatter類來處理。例如&#xff1a; //實例化一個NSDateFormatter對象 NSDateFormatter *dateFormatter [[NSDateFormatter alloc] init]; //設定時間格式,這里可…

微服務架構下分布式事務解決方案 —— 阿里GTS

1 微服務的發展 微服務倡導將復雜的單體應用拆分為若干個功能簡單、松耦合的服務&#xff0c;這樣可以降低開發難度、增強擴展性、便于敏捷開發。當前被越來越多的開發者推崇&#xff0c;很多互聯網行業巨頭、開源社區等都開始了微服務的討論和實踐。Hailo有160個不同服務構成&…

重要消息丨.NET Core 3.1 將于今年12月13日結束支持

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;5分鐘).NET Core 3.1 將于 2022 年 12 月 13 日結束支持。此后&#xff0c;Microsoft 將不再為 .NET Core 3.1 提供服務更新或技術支持。我們建議盡快遷移到 .NET 6。如果您在支持日期結束后仍在使用 .NET Core 3.1&a…

產品設計的三大原則

1.它有用嗎? 如果我們必須從這三個特性中選擇一個作為最重要的&#xff0c;那就是有用性。 首要的是&#xff0c;一個產品必須有用。如果它無用&#xff0c;其它任何東西都是不相關的&#xff0c;因為沒有人會需要它。很明顯&#xff0c;有用性和可享用性看上去一樣重要&#…

常用的17個運維監控系統

1. Zabbix Zabbix 作為企業級的網絡監控工具&#xff0c;通過從服務器&#xff0c;虛擬機和網絡設備收集的數據提供實時監控&#xff0c;自動發現&#xff0c;映射和可擴展等功能。 Zabbix的企業級監控軟件為用戶提供內置的Java應用服務器監控&#xff0c;硬件監控&#xff0c…

關于html-三角的制作

因為最近看到別人寫的不錯的樣式&#xff0c;所以就想自己實現&#xff0c;但是呢用到了一個三角形&#xff0c;所以稍微研究一下。效果是這樣的&#xff1a;注意是下邊那個淺色三角&#xff0c;感覺書簽的效果有木有。看著很有層次感。接下來就是實現了&#xff0c;利用border…

ABP中的數據過濾器

本文首先介紹了ABP內置的軟刪除過濾器(ISoftDelete)和多租戶過濾器(IMultiTenant)&#xff0c;然后介紹了如何實現一個自定義過濾器&#xff0c;最后介紹了在軟件開發過程中遇到的實際問題&#xff0c;同時給出了解決問題的一個未必最優的思路。一.預定義過濾器ABP中的數據過濾…