# MiniTheme **Repository Path**: hopesy/MiniTheme ## Basic Information - **Project Name**: MiniTheme - **Description**: WPF样式练手项目,主题切换、本地化、自定义控件等 - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-10-22 - **Last Updated**: 2025-10-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MiniTheme > 基于 WPF 的现代化主题系统演示项目,展示了主题切换、多语言支持和 WPF 自定义控件库的最佳实践。 ## 目录 - [核心特性](#核心特性) - [技术栈](#技术栈) - [项目结构](#项目结构) - [核心功能](#核心功能) - [主题系统](#1-主题系统) - [多语言支持](#2-多语言支持) - [自定义控件库 - IconButton](#3-自定义控件库-minithemeui) - [依赖注入架构](#4-依赖注入架构) - [快速开始](#快速开始) - [配置说明](#配置说明) - [代码示例](#代码示例) - [IconButton 技术细节](#iconbutton-技术细节) - [架构亮点](#架构亮点) ## 核心特性 - **主题系统**:亮色/暗色主题动态切换,自动跟随 Windows 系统主题 - **多语言支持**:支持中文、英文、日文、韩文运行时切换 - **自定义控件库**:独立的 MiniTheme.Ui 控件库,包含 IconButton 等控件 - **现代化架构**:基于 Generic Host、依赖注入、MVVM 模式 ## 技术栈 - **.NET 8.0** + **WPF** - **CommunityToolkit.Mvvm** - MVVM 工具库 - **Microsoft.Extensions.Hosting** - 应用程序宿主 - **Microsoft.Extensions.DependencyInjection** - 依赖注入 ## 项目结构 ``` MiniTheme/ ├── MiniTheme/ # 主应用程序 │ ├── Models/ # 数据模型 │ ├── Services/ # 业务服务层 │ │ ├── Interfaces/ # 服务接口 │ │ ├── ThemeService.cs # 主题服务 │ │ ├── LanguageService.cs # 语言服务 │ │ ├── ConfigService.cs # 配置服务 │ │ ├── NavigationService.cs # 导航服务 │ │ └── SystemThemeMonitor.cs # 系统主题监控 │ ├── ViewModels/ # MVVM 视图模型 │ ├── Views/ # XAML 视图 │ │ ├── MainWindow.xaml │ │ └── Pages/ # 子页面视图 │ ├── Themes/ # 主题资源字典 │ │ ├── LightTheme.xaml │ │ └── DarkTheme.xaml │ ├── Resources/ # 样式和语言资源 │ └── appsettings.json # 应用配置 │ └── MiniTheme.Ui/ # 自定义控件库 ├── Controls/ # 自定义控件 │ └── IconButton.cs # 图标按钮控件 ├── Converters/ # 值转换器 ├── Themes/ # 控件主题 │ └── Generic.xaml # 默认样式 └── Resources/ # 字体等资源 ``` ## 核心功能 ### 1. 主题系统 - **动态主题切换**:通过 `ThemeService` 动态加载 `LightTheme.xaml` 或 `DarkTheme.xaml` - **系统主题监控**:监听 Windows 注册表,自动跟随系统主题变化 - **资源字典**:使用 `DynamicResource` 实现运行时主题更新 ### 2. 多语言支持 - **运行时切换**:通过 `LanguageService` 动态加载语言资源字典 - **支持语言**:简体中文、英文、日文、韩文 ### 3. 自定义控件库 (MiniTheme.Ui) #### IconButton 控件架构 **核心设计**: - **自定义控件**:继承 `Button`,通过 `ControlTemplate` 自定义外观 - **图标字体**:使用 iconfont 字体文件,通过 Unicode 显示图标 - **枚举驱动**:使用 `IconType` 枚举定义图标类型,通过转换器映射到 Unicode **关键组件**: ``` MiniTheme.Ui/ ├── Controls/ │ └── IconButton.cs # 控件定义,包含依赖属性 ├── Enums/ │ └── IconType.cs # 图标类型枚举 ├── Converters/ │ ├── IconToUnicodeConverter.cs # 枚举到 Unicode 转换器 │ └── LeftMarginConverter.cs # 间距计算转换器 ├── Themes/ │ └── Generic.xaml # 控件库入口 ├── IconButton.xaml # 默认样式和模板 └── Resources/Fonts/ └── iconfont.ttf # 字体文件 ``` **依赖属性**: - `Icon` - 图标类型(枚举) - `IconSize` - 图标大小(默认 16) - `Spacing` - 图标与文本间距(默认 8) - `CornerRadius` - 圆角半径(默认 6) - `HoverBackground` - 悬停背景色 - `PressedBackground` - 按下背景色 **交互效果**: - 悬停时增强阴影、改变背景色 - 按下时缩小阴影、轻微缩放(0.98x) - 禁用时降低透明度、移除阴影 ### 4. 依赖注入架构 ```csharp // 服务注册 builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // 视图和 ViewModel 注册 builder.Services.AddSingleton(); builder.Services.AddSingleton(); ``` ## 快速开始 ### 前置要求 - .NET 8.0 SDK - Windows 操作系统 ### 运行项目 ```bash # 克隆项目 git clone # 进入项目目录 cd MiniTheme # 还原依赖 dotnet restore # 运行应用 dotnet run --project MiniTheme ``` 或使用 Visual Studio 2022 打开 `MiniTheme.sln` 直接运行。 ## 配置说明 `appsettings.json` 配置示例: ```json { "AppSettings": { "ThemeMode": "Auto", "Language": "zh-CN" } } ``` **ThemeMode** 选项: - `Light` - 亮色主题 - `Dark` - 暗色主题 - `Auto` - 跟随系统主题 **Language** 选项: - `zh-CN` - 简体中文 - `en-US` - 英文 - `ja-JP` - 日文 - `ko-KR` - 韩文 ## 代码示例 ### IconButton 使用 ```xml ``` **枚举到 Unicode 的转换流程**: ```csharp // 1. 定义枚举 public enum IconType { None = 0, Home = 8, Setting = 5 } // 2. 转换器映射 private static readonly Dictionary IconMap = new() { { IconType.Home, 0xe751 }, { IconType.Setting, 0xe601 } }; // 3. 转换为字符 public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) { if (value is IconType iconType && IconMap.TryGetValue(iconType, out var unicodeValue)) { return char.ConvertFromUtf32(unicodeValue); // 返回对应的图标字符 } return string.Empty; } ``` ### 主题切换 ```csharp // 在 ThemeService 中切换主题 public void ApplyTheme(ThemeMode themeMode) { var themePath = themeMode switch { ThemeMode.Light => "Themes/LightTheme.xaml", ThemeMode.Dark => "Themes/DarkTheme.xaml", _ => throw new ArgumentException("Invalid theme mode") }; var themeDict = new ResourceDictionary { Source = new Uri(themePath, UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(themeDict); } ``` ### XAML 中使用动态资源 ```xml ``` ## IconButton 技术细节 ### 控件模板结构 ```xml ``` ### WPF 自定义控件标准架构 **1. Generic.xaml 模式**: - 位置:`Themes/Generic.xaml`(WPF 约定) - 作用:控件库的默认样式入口 - 自动加载:运行时自动查找并应用 **2. 依赖属性模式**: ```csharp public static readonly DependencyProperty IconProperty = DependencyProperty.Register( nameof(Icon), typeof(IconType), typeof(IconButton), new PropertyMetadata(IconType.None)); public IconType Icon { get => (IconType)GetValue(IconProperty); set => SetValue(IconProperty, value); } ``` **3. 样式继承机制**: - 默认样式:无 `x:Key`,自动应用到所有 `IconButton` - 显式样式:有 `x:Key`,需通过 `BasedOn` 继承默认样式 - 主题样式:在应用程序中动态引用,覆盖默认属性 ### 转换器设计 **IconToUnicodeConverter**: - 输入:`IconType` 枚举 - 输出:Unicode 字符串 - 映射:`Dictionary` **LeftMarginConverter**: - 输入:`double` 间距值 - 输出:`Thickness(spacing, 0, 0, 0)` - 用途:动态计算图标与文本的左边距 ### 样式触发器 ```xml ``` ### 主题集成 **在应用程序中使用**: 1. 引用控件库:`` 2. 声明命名空间:`xmlns:ui="clr-namespace:MiniTheme.Ui.Controls;assembly=MiniTheme.Ui"` 3. 创建主题样式:通过 `TargetType` 覆盖默认属性 ```xml ``` ## 架构亮点 - **MVVM 模式**:清晰的视图-视图模型-模型分离 - **依赖注入**:基于 `Microsoft.Extensions.DependencyInjection` - **Generic Host**:统一应用生命周期管理(`IHostedService`) - **Options Pattern**:强类型配置,支持热重载 - **资源字典**:主题和语言动态加载 ## 许可证 MIT License