Whp.WPF.Themes
0.0.3
.NET 8.0
This package targets .NET 8.0. The package is compatible with this framework or higher.
.NET Framework 4.7.2
This package targets .NET Framework 4.7.2. The package is compatible with this framework or higher.
dotnet add package Whp.WPF.Themes --version 0.0.3
NuGet\Install-Package Whp.WPF.Themes -Version 0.0.3
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Whp.WPF.Themes" Version="0.0.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Whp.WPF.Themes" Version="0.0.3" />
<PackageReference Include="Whp.WPF.Themes" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Whp.WPF.Themes --version 0.0.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Whp.WPF.Themes, 0.0.3"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Whp.WPF.Themes@0.0.3
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Whp.WPF.Themes&version=0.0.3
#tool nuget:?package=Whp.WPF.Themes&version=0.0.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
在 WPF 桌面应用开发中如何使用?
前提条件
引用
Whp.WPF.Themes命名空间。准备好资源文件夹,包含:主题、样式、字体等 XAML 文件以及自定义的资源目录类。资源文件夹结构示例:
Resources/ ├── Themes/ │ ├── Theme.Fonts.xaml │ ├── Theme.Colors.xaml │ ├── Theme.Dark.xaml │ ├── Theme.Light.xaml │ └── ... ├── Styles/ │ ├── Common.xaml │ ├── TextBlock.xaml │ ├── Button.xaml │ ├── TextBox.xaml │ └── ... └── AutoCadThemeCatalog.cs⚠️ 资源文件中所有 XAML 文件的 Build Action 必须设为 Page,否则 pack:// URI 加载会失败并抛出 XamlParseException。
1. 主题检测器
- 推荐使用
Whp.WPF.Themes.Detection提供的WindowsThemeDetector类。 - 自定义创建了一个名为主题检测器的类,继承自
IThemeDetector接口,并实现GetSystemTheme()和ObserveSystemTheme()方法。
2. 定义桌面应用的资源目录
创建资源目录类,告诉引擎你的 XAML 资源文件在哪里、按什么顺序加载;
推荐继承 ThemeResourcesBase:
using System.Reflection;
using Whp.WPF.Themes;
public class DesktopThemeCatalog : ThemeResourcesBase
{
public override string AssemblyName => Assembly.GetExecutingAssembly().GetName().Name;
public override IReadOnlyList<string> GetPaths(ThemeMode mode)
{
var themeFile = mode switch
{
ThemeMode.Dark => "Resources/Themes/Theme.Dark.xaml",
ThemeMode.Light => "Resources/Themes/Theme.Light.xaml",
_ => "Resources/Themes/Theme.Light.xaml"
};
return new List<string>
{
"Resources/Themes/Theme.Fonts.xaml",
"Resources/Themes/Theme.Colors.xaml",
themeFile,
"Resources/Styles/Common.xaml",
"Resources/Styles/TextBlock.xaml",
"Resources/Styles/Button.xaml",
"Resources/Styles/TextBox.xaml",
"Resources/Styles/ComboBox.xaml",
"Resources/Styles/CheckBox.xaml",
"Resources/Styles/RadioButton.xaml",
"Resources/Styles/GroupBox.xaml",
"Resources/Styles/Window.xaml"
};
}
}
路径规则:
- 使用 / 分隔(pack URI 规范),不要用 \。
- 路径相对程序集根,不能带前导 /,大小写敏感。
- 顺序即加载顺序,后加载覆盖先加载的同名 Key。
- 推荐顺序:基础变量(Fonts / Colors)→ 主题(Dark / Light)→ 控件样式 → 自定义覆盖。
- ThemeMode 目前只有 Light / Dark,建议用 switch 而非三元表达式,便于将来扩展。
实例化建议:
使用静态单例复用 catalog,避免每次 Apply 都 new 一个实例(丢失内部缓存):
internal static readonly AutoCadThemeCatalog Catalog = new();
3. 在应用启动时初始化引擎
在 App.xaml.cs 的 OnStartup 中完成一次性配置。引擎作为静态单例,全局共享。
using System.Windows;
using Whp.WPF.Themes;
using Whp.WPF.Themes.Detection;
public partial class App : Application
{
/// <summary>全局共享的主题引擎。</summary>
internal static ThemeManager Theme { get; private set; } = null!;
/// <summary>全局共享的资源目录单例。</summary>
internal static readonly DesktopThemeCatalog Catalog = new();
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// 1) 创建持久化提供者(可选)。
// 不传 = 纯内存状态,每次启动都跟随 CAD;
// 传入 = 记住用户上次选择的 ThemeOption。
//
// ⚠️ 持久化文件不要写入 Program Files,应放在:
// - %AppData%\MyCadPlugin\theme.json
// - 或插件自身的用户配置目录
IThemeSettingsProvider settings =
new JsonThemeSettingsProvider(
System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"MyCadPlugin",
"theme.json"));
// 2) 创建引擎
Theme = new ThemeManager(settings);
// 3) 注册 Windows 桌面主题检测器
Theme.Register(new WindowsThemeDetector());
// 4) 可选:监听主题变化做额外业务逻辑
Theme.ThemeChanged += (s, e) =>
{
System.Diagnostics.Debug.WriteLine(
$"[App] Theme: {e.OldMode} → {e.NewMode}");
// 在此更新非 WPF 资源(图标、原生控件等),见第 9 节
};
}
protected override void OnExit(ExitEventArgs e)
{
Theme?.Dispose();
base.OnExit(e);
}
}
4. 在 WPF 窗口/用户控件中应用主题
using System.Windows;
using Whp.WPF.Themes;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// 一行代码应用主题:
// FollowSystem = 跟随 Windows 深浅色设置自动切换
App.Theme.Apply(this, App.Catalog, ThemeOption.FollowSystem);
// 之后用户在 Windows 设置里切换"应用模式"时,
// 此窗口会自动刷新,无需手动处理。
}
}
注意事项:
- 调用时机:在 InitializeComponent() 之后 调用。
- 新窗口:每个新窗口/面板在构造时调用一次 Apply 即可,关闭后引擎会自动从跟踪列表移除(弱引用 + Unloaded 事件)。
运行时切换主题
典型场景:设置页让用户选择浅色 / 深色 / 跟随系统。
// 读取当前选项
ThemeOption current = App.Theme.SelectedOption;
// 用户点击"深色"
App.Theme.SelectedOption = ThemeOption.Dark;
// → 自动持久化 + 刷新所有已 Apply 的窗口 + 触发 ThemeChanged 事件
// 用户点击"跟随系统"
App.Theme.SelectedOption = ThemeOption.FollowSystem;
// → 立即取 Windows 当前设置,并开始跟随系统变化
引擎自动完成:
- 将新选项写入 IThemeSettingsProvider;
- 重新解析生效主题;
- 刷新所有已注册的目标元素;
- 触发 ThemeChanged 事件。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows7.0 is compatible. net9.0-windows was computed. net10.0-windows was computed. net10.0-windows7.0 is compatible. |
| .NET Framework | net472 is compatible. net48 is compatible. net481 was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
.NETFramework 4.7.2
- No dependencies.
-
.NETFramework 4.8
- No dependencies.
-
net10.0-windows7.0
- No dependencies.
-
net8.0-windows7.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.3 | 88 | 9/13/2026 |