[{"data":1,"prerenderedAt":1537},["ShallowReactive",2],{"page-\u002Fcsharp\u002Fwpf\u002F基于资源字典实现主题切换":3},{"id":4,"title":5,"body":6,"description":185,"extension":1531,"meta":1532,"navigation":801,"path":1533,"seo":1534,"stem":1535,"__hash__":1536},"content\u002Fcsharp\u002FWPF\u002F基于资源字典实现主题切换.md","基于资源字典实现主题切换",{"type":7,"value":8,"toc":1500},"minimark",[9,12,32,35,40,80,82,85,90,164,175,179,231,237,254,256,260,264,267,272,354,359,387,414,418,423,580,585,603,607,612,637,644,667,671,676,772,774,778,782,1064,1068,1128,1130,1134,1138,1167,1171,1220,1224,1246,1250,1270,1272,1276,1280,1291,1299,1303,1308,1312,1332,1336,1341,1346,1395,1399,1409,1413,1425,1427,1431,1454,1456,1460,1494,1496],[10,11,5],"h1",{"id":5},[13,14,15],"blockquote",{},[16,17,18,22,23,27,28,31],"p",{},[19,20,21],"strong",{},"核心原理","：WPF 的主题切换通过动态替换 ",[24,25,26],"code",{},"Application.Resources.MergedDictionaries"," 中的资源字典实现。所有使用 ",[24,29,30],{},"DynamicResource"," 绑定的控件会自动更新。",[33,34],"hr",{},[36,37,39],"h2",{"id":38},"目录","📋 目录",[41,42,43,52,59,66,73],"ul",{},[44,45,46],"li",{},[47,48,49],"span",{},[47,50,51],{},"#核心原理",[44,53,54],{},[47,55,56],{},[47,57,58],{},"#实现步骤",[44,60,61],{},[47,62,63],{},[47,64,65],{},"#代码实现",[44,67,68],{},[47,69,70],{},[47,71,72],{},"#关键要点",[44,74,75],{},[47,76,77],{},[47,78,79],{},"#常见问题",[33,81],{},[36,83,84],{"id":21},"🎯 核心原理",[86,87,89],"h3",{"id":88},"_1-dynamicresource-vs-staticresource","1. DynamicResource vs StaticResource",[91,92,93,108],"table",{},[94,95,96],"thead",{},[97,98,99,103,106],"tr",{},[100,101,102],"th",{},"特性",[100,104,105],{},"StaticResource",[100,107,30],{},[109,110,111,125,138,151],"tbody",{},[97,112,113,119,122],{},[114,115,116],"td",{},[19,117,118],{},"查找时机",[114,120,121],{},"编译时\u002F启动时查找一次",[114,123,124],{},"运行时持续监听资源变化",[97,126,127,132,135],{},[114,128,129],{},[19,130,131],{},"性能",[114,133,134],{},"更快",[114,136,137],{},"稍慢（需要运行时查找）",[97,139,140,145,148],{},[114,141,142],{},[19,143,144],{},"主题切换",[114,146,147],{},"❌ 不支持",[114,149,150],{},"✅ 支持",[97,152,153,158,161],{},[114,154,155],{},[19,156,157],{},"使用场景",[114,159,160],{},"固定资源",[114,162,163],{},"可切换的主题资源",[13,165,166],{},[16,167,168,171,172,174],{},[19,169,170],{},"⚠️ 重要","：主题切换必须使用 ",[24,173,30],{},"，否则资源字典替换后控件不会更新。",[86,176,178],{"id":177},"_2-资源字典替换机制","2. 资源字典替换机制",[180,181,186],"pre",{"className":182,"code":183,"language":184,"meta":185,"style":185},"language-mermaid shiki shiki-themes github-light github-dark","graph LR\n    A[Application.Resources] --> B[MergedDictionaries]\n    B --> C[LightTheme.xaml]\n    B --> D[DarkTheme.xaml]\n    \n    E[UI控件] --> F{DynamicResource}\n    F --> B\n","mermaid","",[24,187,188,195,201,207,213,219,225],{"__ignoreMap":185},[47,189,192],{"class":190,"line":191},"line",1,[47,193,194],{},"graph LR\n",[47,196,198],{"class":190,"line":197},2,[47,199,200],{},"    A[Application.Resources] --> B[MergedDictionaries]\n",[47,202,204],{"class":190,"line":203},3,[47,205,206],{},"    B --> C[LightTheme.xaml]\n",[47,208,210],{"class":190,"line":209},4,[47,211,212],{},"    B --> D[DarkTheme.xaml]\n",[47,214,216],{"class":190,"line":215},5,[47,217,218],{},"    \n",[47,220,222],{"class":190,"line":221},6,[47,223,224],{},"    E[UI控件] --> F{DynamicResource}\n",[47,226,228],{"class":190,"line":227},7,[47,229,230],{},"    F --> B\n",[16,232,233,236],{},[19,234,235],{},"工作流程","：",[238,239,240,243,246,251],"ol",{},[44,241,242],{},"移除旧的主题资源字典",[44,244,245],{},"加载新的主题资源字典",[44,247,248,250],{},[24,249,30],{}," 自动重新查找资源",[44,252,253],{},"UI 自动更新",[33,255],{},[36,257,259],{"id":258},"️-实现步骤","🛠️ 实现步骤",[86,261,263],{"id":262},"步骤-1创建主题资源字典","步骤 1：创建主题资源字典",[16,265,266],{},"创建两个资源字典文件，定义不同主题的颜色和样式：",[16,268,269],{},[19,270,271],{},"Themes\u002FLightTheme.xaml",[180,273,277],{"className":274,"code":275,"language":276,"meta":185,"style":185},"language-xml shiki shiki-themes github-light github-dark","\u003CResourceDictionary xmlns=\"...\">\n    \u003C!-- 颜色定义 -->\n    \u003CColor x:Key=\"BackgroundColor\">#FFFFFF\u003C\u002FColor>\n    \u003CColor x:Key=\"ForegroundColor\">#212121\u003C\u002FColor>\n    \n    \u003C!-- 画刷定义（使用 StaticResource，因为颜色在同一字典中） -->\n    \u003CSolidColorBrush x:Key=\"BackgroundBrush\" Color=\"{StaticResource BackgroundColor}\"\u002F>\n    \u003CSolidColorBrush x:Key=\"ForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"\u002F>\n    \n    \u003C!-- 隐式样式 -->\n    \u003CStyle TargetType=\"Button\">\n        \u003CSetter Property=\"Background\" Value=\"{DynamicResource PrimaryBrush}\"\u002F>\n    \u003C\u002FStyle>\n\u003C\u002FResourceDictionary>\n","xml",[24,278,279,284,289,294,299,303,308,313,319,324,330,336,342,348],{"__ignoreMap":185},[47,280,281],{"class":190,"line":191},[47,282,283],{},"\u003CResourceDictionary xmlns=\"...\">\n",[47,285,286],{"class":190,"line":197},[47,287,288],{},"    \u003C!-- 颜色定义 -->\n",[47,290,291],{"class":190,"line":203},[47,292,293],{},"    \u003CColor x:Key=\"BackgroundColor\">#FFFFFF\u003C\u002FColor>\n",[47,295,296],{"class":190,"line":209},[47,297,298],{},"    \u003CColor x:Key=\"ForegroundColor\">#212121\u003C\u002FColor>\n",[47,300,301],{"class":190,"line":215},[47,302,218],{},[47,304,305],{"class":190,"line":221},[47,306,307],{},"    \u003C!-- 画刷定义（使用 StaticResource，因为颜色在同一字典中） -->\n",[47,309,310],{"class":190,"line":227},[47,311,312],{},"    \u003CSolidColorBrush x:Key=\"BackgroundBrush\" Color=\"{StaticResource BackgroundColor}\"\u002F>\n",[47,314,316],{"class":190,"line":315},8,[47,317,318],{},"    \u003CSolidColorBrush x:Key=\"ForegroundBrush\" Color=\"{StaticResource ForegroundColor}\"\u002F>\n",[47,320,322],{"class":190,"line":321},9,[47,323,218],{},[47,325,327],{"class":190,"line":326},10,[47,328,329],{},"    \u003C!-- 隐式样式 -->\n",[47,331,333],{"class":190,"line":332},11,[47,334,335],{},"    \u003CStyle TargetType=\"Button\">\n",[47,337,339],{"class":190,"line":338},12,[47,340,341],{},"        \u003CSetter Property=\"Background\" Value=\"{DynamicResource PrimaryBrush}\"\u002F>\n",[47,343,345],{"class":190,"line":344},13,[47,346,347],{},"    \u003C\u002FStyle>\n",[47,349,351],{"class":190,"line":350},14,[47,352,353],{},"\u003C\u002FResourceDictionary>\n",[16,355,356],{},[19,357,358],{},"Themes\u002FDarkTheme.xaml",[180,360,362],{"className":274,"code":361,"language":276,"meta":185,"style":185},"\u003CResourceDictionary xmlns=\"...\">\n    \u003CColor x:Key=\"BackgroundColor\">#121212\u003C\u002FColor>\n    \u003CColor x:Key=\"ForegroundColor\">#FFFFFF\u003C\u002FColor>\n    \u003C!-- ... -->\n\u003C\u002FResourceDictionary>\n",[24,363,364,368,373,378,383],{"__ignoreMap":185},[47,365,366],{"class":190,"line":191},[47,367,283],{},[47,369,370],{"class":190,"line":197},[47,371,372],{},"    \u003CColor x:Key=\"BackgroundColor\">#121212\u003C\u002FColor>\n",[47,374,375],{"class":190,"line":203},[47,376,377],{},"    \u003CColor x:Key=\"ForegroundColor\">#FFFFFF\u003C\u002FColor>\n",[47,379,380],{"class":190,"line":209},[47,381,382],{},"    \u003C!-- ... -->\n",[47,384,385],{"class":190,"line":215},[47,386,353],{},[13,388,389,394],{},[16,390,391,236],{},[19,392,393],{},"💡 提示",[41,395,396,401,407],{},[44,397,398,399],{},"颜色定义在同一字典中，使用 ",[24,400,105],{},[44,402,403,404,406],{},"画刷和样式使用 ",[24,405,30],{}," 引用颜色",[44,408,409,410,413],{},"隐式样式（无 ",[24,411,412],{},"x:Key","）会自动应用到所有对应类型的控件",[86,415,417],{"id":416},"步骤-2实现主题切换服务","步骤 2：实现主题切换服务",[16,419,420],{},[19,421,422],{},"Services\u002FThemeService.cs",[180,424,428],{"className":425,"code":426,"language":427,"meta":185,"style":185},"language-csharp shiki shiki-themes github-light github-dark","public static class ThemeService\n{\n    public static void SwitchTheme(string themeName)\n    {\n        var app = Application.Current;\n        if (app?.Resources is not ResourceDictionary rootResources) return;\n        \n        \u002F\u002F 移除现有的主题资源字典\n        var themesToRemove = rootResources.MergedDictionaries\n            .Where(d => d.Source?.OriginalString.Contains(\"Theme.xaml\") == true)\n            .ToList();\n        \n        foreach (var theme in themesToRemove)\n        {\n            rootResources.MergedDictionaries.Remove(theme);\n        }\n        \n        \u002F\u002F 加载新主题\n        var assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;\n        var newTheme = new ResourceDictionary\n        {\n            Source = new System.Uri($\"\u002F{assemblyName};component\u002FThemes\u002F{themeName}Theme.xaml\", \n                                    System.UriKind.Relative)\n        };\n        \n        rootResources.MergedDictionaries.Add(newTheme);\n    }\n}\n","csharp",[24,429,430,435,440,445,450,455,460,465,470,475,480,485,489,494,499,505,511,516,522,528,534,539,545,551,557,562,568,574],{"__ignoreMap":185},[47,431,432],{"class":190,"line":191},[47,433,434],{},"public static class ThemeService\n",[47,436,437],{"class":190,"line":197},[47,438,439],{},"{\n",[47,441,442],{"class":190,"line":203},[47,443,444],{},"    public static void SwitchTheme(string themeName)\n",[47,446,447],{"class":190,"line":209},[47,448,449],{},"    {\n",[47,451,452],{"class":190,"line":215},[47,453,454],{},"        var app = Application.Current;\n",[47,456,457],{"class":190,"line":221},[47,458,459],{},"        if (app?.Resources is not ResourceDictionary rootResources) return;\n",[47,461,462],{"class":190,"line":227},[47,463,464],{},"        \n",[47,466,467],{"class":190,"line":315},[47,468,469],{},"        \u002F\u002F 移除现有的主题资源字典\n",[47,471,472],{"class":190,"line":321},[47,473,474],{},"        var themesToRemove = rootResources.MergedDictionaries\n",[47,476,477],{"class":190,"line":326},[47,478,479],{},"            .Where(d => d.Source?.OriginalString.Contains(\"Theme.xaml\") == true)\n",[47,481,482],{"class":190,"line":332},[47,483,484],{},"            .ToList();\n",[47,486,487],{"class":190,"line":338},[47,488,464],{},[47,490,491],{"class":190,"line":344},[47,492,493],{},"        foreach (var theme in themesToRemove)\n",[47,495,496],{"class":190,"line":350},[47,497,498],{},"        {\n",[47,500,502],{"class":190,"line":501},15,[47,503,504],{},"            rootResources.MergedDictionaries.Remove(theme);\n",[47,506,508],{"class":190,"line":507},16,[47,509,510],{},"        }\n",[47,512,514],{"class":190,"line":513},17,[47,515,464],{},[47,517,519],{"class":190,"line":518},18,[47,520,521],{},"        \u002F\u002F 加载新主题\n",[47,523,525],{"class":190,"line":524},19,[47,526,527],{},"        var assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;\n",[47,529,531],{"class":190,"line":530},20,[47,532,533],{},"        var newTheme = new ResourceDictionary\n",[47,535,537],{"class":190,"line":536},21,[47,538,498],{},[47,540,542],{"class":190,"line":541},22,[47,543,544],{},"            Source = new System.Uri($\"\u002F{assemblyName};component\u002FThemes\u002F{themeName}Theme.xaml\", \n",[47,546,548],{"class":190,"line":547},23,[47,549,550],{},"                                    System.UriKind.Relative)\n",[47,552,554],{"class":190,"line":553},24,[47,555,556],{},"        };\n",[47,558,560],{"class":190,"line":559},25,[47,561,464],{},[47,563,565],{"class":190,"line":564},26,[47,566,567],{},"        rootResources.MergedDictionaries.Add(newTheme);\n",[47,569,571],{"class":190,"line":570},27,[47,572,573],{},"    }\n",[47,575,577],{"class":190,"line":576},28,[47,578,579],{},"}\n",[16,581,582,236],{},[19,583,584],{},"关键点",[41,586,587,594,597],{},[44,588,589,590,593],{},"✅ 使用 ",[24,591,592],{},"component"," URI 格式加载嵌入资源",[44,595,596],{},"✅ 通过文件名识别主题资源字典（包含 \"Theme.xaml\"）",[44,598,599,600,602],{},"✅ WPF 的 ",[24,601,30],{}," 会自动更新，无需手动刷新",[86,604,606],{"id":605},"步骤-3在-xaml-中使用-dynamicresource","步骤 3：在 XAML 中使用 DynamicResource",[16,608,609],{},[19,610,611],{},"MainWindow.xaml",[180,613,615],{"className":274,"code":614,"language":276,"meta":185,"style":185},"\u003CWindow Background=\"{DynamicResource BackgroundBrush}\">\n    \u003CButton Content=\"切换主题\" \n            Background=\"{DynamicResource PrimaryBrush}\"\u002F>\n\u003C\u002FWindow>\n",[24,616,617,622,627,632],{"__ignoreMap":185},[47,618,619],{"class":190,"line":191},[47,620,621],{},"\u003CWindow Background=\"{DynamicResource BackgroundBrush}\">\n",[47,623,624],{"class":190,"line":197},[47,625,626],{},"    \u003CButton Content=\"切换主题\" \n",[47,628,629],{"class":190,"line":203},[47,630,631],{},"            Background=\"{DynamicResource PrimaryBrush}\"\u002F>\n",[47,633,634],{"class":190,"line":209},[47,635,636],{},"\u003C\u002FWindow>\n",[16,638,639,236],{},[19,640,641,642],{},"所有需要主题化的属性都必须使用 ",[24,643,30],{},[41,645,646,651,656,661],{},[44,647,648],{},[24,649,650],{},"Background",[44,652,653],{},[24,654,655],{},"Foreground",[44,657,658],{},[24,659,660],{},"BorderBrush",[44,662,663,664],{},"样式中的 ",[24,665,666],{},"Setter.Value",[86,668,670],{"id":669},"步骤-4绑定主题切换命令","步骤 4：绑定主题切换命令",[16,672,673],{},[19,674,675],{},"MainViewModel.cs",[180,677,679],{"className":425,"code":678,"language":427,"meta":185,"style":185},"public partial class MainViewModel : ObservableObject\n{\n    [ObservableProperty]\n    private string _themeButtonText = \"切换到深色主题\";\n    \n    [RelayCommand]\n    private void ToggleTheme()\n    {\n        if (ThemeService.GetCurrentTheme() == \"Light\")\n        {\n            ThemeService.SwitchTheme(\"Dark\");\n            ThemeButtonText = \"切换到浅色主题\";\n        }\n        else\n        {\n            ThemeService.SwitchTheme(\"Light\");\n            ThemeButtonText = \"切换到深色主题\";\n        }\n    }\n}\n",[24,680,681,686,690,695,700,704,709,714,718,723,727,732,737,741,746,750,755,760,764,768],{"__ignoreMap":185},[47,682,683],{"class":190,"line":191},[47,684,685],{},"public partial class MainViewModel : ObservableObject\n",[47,687,688],{"class":190,"line":197},[47,689,439],{},[47,691,692],{"class":190,"line":203},[47,693,694],{},"    [ObservableProperty]\n",[47,696,697],{"class":190,"line":209},[47,698,699],{},"    private string _themeButtonText = \"切换到深色主题\";\n",[47,701,702],{"class":190,"line":215},[47,703,218],{},[47,705,706],{"class":190,"line":221},[47,707,708],{},"    [RelayCommand]\n",[47,710,711],{"class":190,"line":227},[47,712,713],{},"    private void ToggleTheme()\n",[47,715,716],{"class":190,"line":315},[47,717,449],{},[47,719,720],{"class":190,"line":321},[47,721,722],{},"        if (ThemeService.GetCurrentTheme() == \"Light\")\n",[47,724,725],{"class":190,"line":326},[47,726,498],{},[47,728,729],{"class":190,"line":332},[47,730,731],{},"            ThemeService.SwitchTheme(\"Dark\");\n",[47,733,734],{"class":190,"line":338},[47,735,736],{},"            ThemeButtonText = \"切换到浅色主题\";\n",[47,738,739],{"class":190,"line":344},[47,740,510],{},[47,742,743],{"class":190,"line":350},[47,744,745],{},"        else\n",[47,747,748],{"class":190,"line":501},[47,749,498],{},[47,751,752],{"class":190,"line":507},[47,753,754],{},"            ThemeService.SwitchTheme(\"Light\");\n",[47,756,757],{"class":190,"line":513},[47,758,759],{},"            ThemeButtonText = \"切换到深色主题\";\n",[47,761,762],{"class":190,"line":518},[47,763,510],{},[47,765,766],{"class":190,"line":524},[47,767,573],{},[47,769,770],{"class":190,"line":530},[47,771,579],{},[33,773],{},[36,775,777],{"id":776},"完整代码实现","📝 完整代码实现",[86,779,781],{"id":780},"themeservicecs","ThemeService.cs",[180,783,785],{"className":425,"code":784,"language":427,"meta":185,"style":185},"using System.Linq;\nusing System.Windows;\n\nnamespace ColorSwitchSolution.Services;\n\n\u002F\u002F\u002F \u003Csummary>\n\u002F\u002F\u002F 主题切换服务：通过动态替换资源字典实现主题切换\n\u002F\u002F\u002F \u003C\u002Fsummary>\npublic static class ThemeService\n{\n    \u002F\u002F\u002F \u003Csummary>\n    \u002F\u002F\u002F 切换主题\n    \u002F\u002F\u002F \u003C\u002Fsummary>\n    \u002F\u002F\u002F \u003Cparam name=\"themeName\">主题名称（Light 或 Dark）\u003C\u002Fparam>\n    public static void SwitchTheme(string themeName)\n    {\n        var app = Application.Current;\n        if (app?.Resources is not ResourceDictionary rootResources) return;\n        \n        \u002F\u002F 移除现有的主题资源字典\n        var themesToRemove = rootResources.MergedDictionaries\n            .Where(d => d.Source?.OriginalString.Contains(\"Theme.xaml\") == true)\n            .ToList();\n        \n        foreach (var theme in themesToRemove)\n        {\n            rootResources.MergedDictionaries.Remove(theme);\n        }\n        \n        \u002F\u002F 加载新主题\n        var assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;\n        var newTheme = new ResourceDictionary\n        {\n            Source = new System.Uri($\"\u002F{assemblyName};component\u002FThemes\u002F{themeName}Theme.xaml\", \n                                    System.UriKind.Relative)\n        };\n        \n        rootResources.MergedDictionaries.Add(newTheme);\n    }\n    \n    \u002F\u002F\u002F \u003Csummary>\n    \u002F\u002F\u002F 获取当前主题名称\n    \u002F\u002F\u002F \u003C\u002Fsummary>\n    public static string GetCurrentTheme()\n    {\n        var app = Application.Current;\n        if (app?.Resources is not ResourceDictionary rootResources) return \"Light\";\n        \n        var currentTheme = rootResources.MergedDictionaries\n            .FirstOrDefault(d => d.Source?.OriginalString.Contains(\"Theme.xaml\") == true);\n        \n        if (currentTheme?.Source?.OriginalString.Contains(\"DarkTheme\") == true)\n            return \"Dark\";\n        \n        return \"Light\";\n    }\n}\n",[24,786,787,792,797,803,808,812,817,822,827,831,835,840,845,850,855,859,863,867,871,875,879,883,887,891,895,899,903,907,911,916,921,926,931,936,941,946,951,956,961,966,971,976,982,987,993,998,1003,1009,1014,1020,1026,1031,1037,1043,1048,1054,1059],{"__ignoreMap":185},[47,788,789],{"class":190,"line":191},[47,790,791],{},"using System.Linq;\n",[47,793,794],{"class":190,"line":197},[47,795,796],{},"using System.Windows;\n",[47,798,799],{"class":190,"line":203},[47,800,802],{"emptyLinePlaceholder":801},true,"\n",[47,804,805],{"class":190,"line":209},[47,806,807],{},"namespace ColorSwitchSolution.Services;\n",[47,809,810],{"class":190,"line":215},[47,811,802],{"emptyLinePlaceholder":801},[47,813,814],{"class":190,"line":221},[47,815,816],{},"\u002F\u002F\u002F \u003Csummary>\n",[47,818,819],{"class":190,"line":227},[47,820,821],{},"\u002F\u002F\u002F 主题切换服务：通过动态替换资源字典实现主题切换\n",[47,823,824],{"class":190,"line":315},[47,825,826],{},"\u002F\u002F\u002F \u003C\u002Fsummary>\n",[47,828,829],{"class":190,"line":321},[47,830,434],{},[47,832,833],{"class":190,"line":326},[47,834,439],{},[47,836,837],{"class":190,"line":332},[47,838,839],{},"    \u002F\u002F\u002F \u003Csummary>\n",[47,841,842],{"class":190,"line":338},[47,843,844],{},"    \u002F\u002F\u002F 切换主题\n",[47,846,847],{"class":190,"line":344},[47,848,849],{},"    \u002F\u002F\u002F \u003C\u002Fsummary>\n",[47,851,852],{"class":190,"line":350},[47,853,854],{},"    \u002F\u002F\u002F \u003Cparam name=\"themeName\">主题名称（Light 或 Dark）\u003C\u002Fparam>\n",[47,856,857],{"class":190,"line":501},[47,858,444],{},[47,860,861],{"class":190,"line":507},[47,862,449],{},[47,864,865],{"class":190,"line":513},[47,866,454],{},[47,868,869],{"class":190,"line":518},[47,870,459],{},[47,872,873],{"class":190,"line":524},[47,874,464],{},[47,876,877],{"class":190,"line":530},[47,878,469],{},[47,880,881],{"class":190,"line":536},[47,882,474],{},[47,884,885],{"class":190,"line":541},[47,886,479],{},[47,888,889],{"class":190,"line":547},[47,890,484],{},[47,892,893],{"class":190,"line":553},[47,894,464],{},[47,896,897],{"class":190,"line":559},[47,898,493],{},[47,900,901],{"class":190,"line":564},[47,902,498],{},[47,904,905],{"class":190,"line":570},[47,906,504],{},[47,908,909],{"class":190,"line":576},[47,910,510],{},[47,912,914],{"class":190,"line":913},29,[47,915,464],{},[47,917,919],{"class":190,"line":918},30,[47,920,521],{},[47,922,924],{"class":190,"line":923},31,[47,925,527],{},[47,927,929],{"class":190,"line":928},32,[47,930,533],{},[47,932,934],{"class":190,"line":933},33,[47,935,498],{},[47,937,939],{"class":190,"line":938},34,[47,940,544],{},[47,942,944],{"class":190,"line":943},35,[47,945,550],{},[47,947,949],{"class":190,"line":948},36,[47,950,556],{},[47,952,954],{"class":190,"line":953},37,[47,955,464],{},[47,957,959],{"class":190,"line":958},38,[47,960,567],{},[47,962,964],{"class":190,"line":963},39,[47,965,573],{},[47,967,969],{"class":190,"line":968},40,[47,970,218],{},[47,972,974],{"class":190,"line":973},41,[47,975,839],{},[47,977,979],{"class":190,"line":978},42,[47,980,981],{},"    \u002F\u002F\u002F 获取当前主题名称\n",[47,983,985],{"class":190,"line":984},43,[47,986,849],{},[47,988,990],{"class":190,"line":989},44,[47,991,992],{},"    public static string GetCurrentTheme()\n",[47,994,996],{"class":190,"line":995},45,[47,997,449],{},[47,999,1001],{"class":190,"line":1000},46,[47,1002,454],{},[47,1004,1006],{"class":190,"line":1005},47,[47,1007,1008],{},"        if (app?.Resources is not ResourceDictionary rootResources) return \"Light\";\n",[47,1010,1012],{"class":190,"line":1011},48,[47,1013,464],{},[47,1015,1017],{"class":190,"line":1016},49,[47,1018,1019],{},"        var currentTheme = rootResources.MergedDictionaries\n",[47,1021,1023],{"class":190,"line":1022},50,[47,1024,1025],{},"            .FirstOrDefault(d => d.Source?.OriginalString.Contains(\"Theme.xaml\") == true);\n",[47,1027,1029],{"class":190,"line":1028},51,[47,1030,464],{},[47,1032,1034],{"class":190,"line":1033},52,[47,1035,1036],{},"        if (currentTheme?.Source?.OriginalString.Contains(\"DarkTheme\") == true)\n",[47,1038,1040],{"class":190,"line":1039},53,[47,1041,1042],{},"            return \"Dark\";\n",[47,1044,1046],{"class":190,"line":1045},54,[47,1047,464],{},[47,1049,1051],{"class":190,"line":1050},55,[47,1052,1053],{},"        return \"Light\";\n",[47,1055,1057],{"class":190,"line":1056},56,[47,1058,573],{},[47,1060,1062],{"class":190,"line":1061},57,[47,1063,579],{},[86,1065,1067],{"id":1066},"appxaml加载默认主题","App.xaml（加载默认主题）",[180,1069,1071],{"className":274,"code":1070,"language":276,"meta":185,"style":185},"\u003CApplication x:Class=\"ColorSwitchSolution.App\"\n             StartupUri=\"MainWindow.xaml\">\n    \u003CApplication.Resources>\n        \u003CResourceDictionary>\n            \u003CResourceDictionary.MergedDictionaries>\n                \u003C!-- 默认加载浅色主题 -->\n                \u003CResourceDictionary Source=\"\u002FColorSwitchSolution;component\u002FThemes\u002FLightTheme.xaml\"\u002F>\n            \u003C\u002FResourceDictionary.MergedDictionaries>\n        \u003C\u002FResourceDictionary>\n    \u003C\u002FApplication.Resources>\n\u003C\u002FApplication>\n",[24,1072,1073,1078,1083,1088,1093,1098,1103,1108,1113,1118,1123],{"__ignoreMap":185},[47,1074,1075],{"class":190,"line":191},[47,1076,1077],{},"\u003CApplication x:Class=\"ColorSwitchSolution.App\"\n",[47,1079,1080],{"class":190,"line":197},[47,1081,1082],{},"             StartupUri=\"MainWindow.xaml\">\n",[47,1084,1085],{"class":190,"line":203},[47,1086,1087],{},"    \u003CApplication.Resources>\n",[47,1089,1090],{"class":190,"line":209},[47,1091,1092],{},"        \u003CResourceDictionary>\n",[47,1094,1095],{"class":190,"line":215},[47,1096,1097],{},"            \u003CResourceDictionary.MergedDictionaries>\n",[47,1099,1100],{"class":190,"line":221},[47,1101,1102],{},"                \u003C!-- 默认加载浅色主题 -->\n",[47,1104,1105],{"class":190,"line":227},[47,1106,1107],{},"                \u003CResourceDictionary Source=\"\u002FColorSwitchSolution;component\u002FThemes\u002FLightTheme.xaml\"\u002F>\n",[47,1109,1110],{"class":190,"line":315},[47,1111,1112],{},"            \u003C\u002FResourceDictionary.MergedDictionaries>\n",[47,1114,1115],{"class":190,"line":321},[47,1116,1117],{},"        \u003C\u002FResourceDictionary>\n",[47,1119,1120],{"class":190,"line":326},[47,1121,1122],{},"    \u003C\u002FApplication.Resources>\n",[47,1124,1125],{"class":190,"line":332},[47,1126,1127],{},"\u003C\u002FApplication>\n",[33,1129],{},[36,1131,1133],{"id":1132},"关键要点","🔑 关键要点",[86,1135,1137],{"id":1136},"必须使用-dynamicresource","✅ 必须使用 DynamicResource",[180,1139,1141],{"className":274,"code":1140,"language":276,"meta":185,"style":185},"\u003C!-- ✅ 正确：支持主题切换 -->\n\u003CButton Background=\"{DynamicResource PrimaryBrush}\"\u002F>\n\n\u003C!-- ❌ 错误：不支持主题切换 -->\n\u003CButton Background=\"{StaticResource PrimaryBrush}\"\u002F>\n",[24,1142,1143,1148,1153,1157,1162],{"__ignoreMap":185},[47,1144,1145],{"class":190,"line":191},[47,1146,1147],{},"\u003C!-- ✅ 正确：支持主题切换 -->\n",[47,1149,1150],{"class":190,"line":197},[47,1151,1152],{},"\u003CButton Background=\"{DynamicResource PrimaryBrush}\"\u002F>\n",[47,1154,1155],{"class":190,"line":203},[47,1156,802],{"emptyLinePlaceholder":801},[47,1158,1159],{"class":190,"line":209},[47,1160,1161],{},"\u003C!-- ❌ 错误：不支持主题切换 -->\n",[47,1163,1164],{"class":190,"line":215},[47,1165,1166],{},"\u003CButton Background=\"{StaticResource PrimaryBrush}\"\u002F>\n",[86,1168,1170],{"id":1169},"资源字典中的资源引用","✅ 资源字典中的资源引用",[180,1172,1174],{"className":274,"code":1173,"language":276,"meta":185,"style":185},"\u003C!-- 颜色在同一字典中，使用 StaticResource -->\n\u003CColor x:Key=\"BackgroundColor\">#FFFFFF\u003C\u002FColor>\n\u003CSolidColorBrush x:Key=\"BackgroundBrush\" \n                 Color=\"{StaticResource BackgroundColor}\"\u002F>\n\n\u003C!-- 样式引用画刷，使用 DynamicResource -->\n\u003CStyle TargetType=\"Button\">\n    \u003CSetter Property=\"Background\" Value=\"{DynamicResource PrimaryBrush}\"\u002F>\n\u003C\u002FStyle>\n",[24,1175,1176,1181,1186,1191,1196,1200,1205,1210,1215],{"__ignoreMap":185},[47,1177,1178],{"class":190,"line":191},[47,1179,1180],{},"\u003C!-- 颜色在同一字典中，使用 StaticResource -->\n",[47,1182,1183],{"class":190,"line":197},[47,1184,1185],{},"\u003CColor x:Key=\"BackgroundColor\">#FFFFFF\u003C\u002FColor>\n",[47,1187,1188],{"class":190,"line":203},[47,1189,1190],{},"\u003CSolidColorBrush x:Key=\"BackgroundBrush\" \n",[47,1192,1193],{"class":190,"line":209},[47,1194,1195],{},"                 Color=\"{StaticResource BackgroundColor}\"\u002F>\n",[47,1197,1198],{"class":190,"line":215},[47,1199,802],{"emptyLinePlaceholder":801},[47,1201,1202],{"class":190,"line":221},[47,1203,1204],{},"\u003C!-- 样式引用画刷，使用 DynamicResource -->\n",[47,1206,1207],{"class":190,"line":227},[47,1208,1209],{},"\u003CStyle TargetType=\"Button\">\n",[47,1211,1212],{"class":190,"line":315},[47,1213,1214],{},"    \u003CSetter Property=\"Background\" Value=\"{DynamicResource PrimaryBrush}\"\u002F>\n",[47,1216,1217],{"class":190,"line":321},[47,1218,1219],{},"\u003C\u002FStyle>\n",[86,1221,1223],{"id":1222},"隐式样式自动应用","✅ 隐式样式自动应用",[180,1225,1227],{"className":274,"code":1226,"language":276,"meta":185,"style":185},"\u003C!-- 无 x:Key 的样式会自动应用到所有 Button -->\n\u003CStyle TargetType=\"Button\">\n    \u003CSetter Property=\"Background\" Value=\"{DynamicResource PrimaryBrush}\"\u002F>\n\u003C\u002FStyle>\n",[24,1228,1229,1234,1238,1242],{"__ignoreMap":185},[47,1230,1231],{"class":190,"line":191},[47,1232,1233],{},"\u003C!-- 无 x:Key 的样式会自动应用到所有 Button -->\n",[47,1235,1236],{"class":190,"line":197},[47,1237,1209],{},[47,1239,1240],{"class":190,"line":203},[47,1241,1214],{},[47,1243,1244],{"class":190,"line":209},[47,1245,1219],{},[86,1247,1249],{"id":1248},"资源-uri-格式","✅ 资源 URI 格式",[180,1251,1253],{"className":425,"code":1252,"language":427,"meta":185,"style":185},"\u002F\u002F 标准格式：\u002FAssemblyName;component\u002FPath\u002FFile.xaml\nSource = new Uri($\"\u002F{assemblyName};component\u002FThemes\u002F{themeName}Theme.xaml\", \n                 UriKind.Relative)\n",[24,1254,1255,1260,1265],{"__ignoreMap":185},[47,1256,1257],{"class":190,"line":191},[47,1258,1259],{},"\u002F\u002F 标准格式：\u002FAssemblyName;component\u002FPath\u002FFile.xaml\n",[47,1261,1262],{"class":190,"line":197},[47,1263,1264],{},"Source = new Uri($\"\u002F{assemblyName};component\u002FThemes\u002F{themeName}Theme.xaml\", \n",[47,1266,1267],{"class":190,"line":203},[47,1268,1269],{},"                 UriKind.Relative)\n",[33,1271],{},[36,1273,1275],{"id":1274},"常见问题","❓ 常见问题",[86,1277,1279],{"id":1278},"q1-主题切换后控件没有更新","Q1: 主题切换后控件没有更新？",[16,1281,1282,1285,1286,1288,1289],{},[19,1283,1284],{},"原因","：使用了 ",[24,1287,105],{}," 而不是 ",[24,1290,30],{},[16,1292,1293,1296,1297],{},[19,1294,1295],{},"解决","：将所有主题相关的资源绑定改为 ",[24,1298,30],{},[86,1300,1302],{"id":1301},"q2-资源字典加载失败","Q2: 资源字典加载失败？",[16,1304,1305,1307],{},[19,1306,1284],{},"：URI 路径不正确",[16,1309,1310,236],{},[19,1311,1295],{},[41,1313,1314,1321],{},[44,1315,1316,1317,1320],{},"确保使用 ",[24,1318,1319],{},"\u002FAssemblyName;component\u002FPath\u002FFile.xaml"," 格式",[44,1322,1323,1324,1327,1328,1331],{},"确保资源文件设置为 ",[24,1325,1326],{},"Resource"," 或 ",[24,1329,1330],{},"Page"," 生成操作",[86,1333,1335],{"id":1334},"q3-tabcontrol-等控件不受主题影响","Q3: TabControl 等控件不受主题影响？",[16,1337,1338,1340],{},[19,1339,1284],{},"：控件使用了默认模板，没有应用主题样式",[16,1342,1343,1345],{},[19,1344,1295],{},"：在主题资源字典中定义隐式样式，覆盖控件的默认模板",[180,1347,1349],{"className":274,"code":1348,"language":276,"meta":185,"style":185},"\u003CStyle TargetType=\"TabItem\">\n    \u003CSetter Property=\"Template\">\n        \u003CSetter.Value>\n            \u003CControlTemplate TargetType=\"TabItem\">\n                \u003C!-- 自定义模板，使用 DynamicResource -->\n            \u003C\u002FControlTemplate>\n        \u003C\u002FSetter.Value>\n    \u003C\u002FSetter>\n\u003C\u002FStyle>\n",[24,1350,1351,1356,1361,1366,1371,1376,1381,1386,1391],{"__ignoreMap":185},[47,1352,1353],{"class":190,"line":191},[47,1354,1355],{},"\u003CStyle TargetType=\"TabItem\">\n",[47,1357,1358],{"class":190,"line":197},[47,1359,1360],{},"    \u003CSetter Property=\"Template\">\n",[47,1362,1363],{"class":190,"line":203},[47,1364,1365],{},"        \u003CSetter.Value>\n",[47,1367,1368],{"class":190,"line":209},[47,1369,1370],{},"            \u003CControlTemplate TargetType=\"TabItem\">\n",[47,1372,1373],{"class":190,"line":215},[47,1374,1375],{},"                \u003C!-- 自定义模板，使用 DynamicResource -->\n",[47,1377,1378],{"class":190,"line":221},[47,1379,1380],{},"            \u003C\u002FControlTemplate>\n",[47,1382,1383],{"class":190,"line":227},[47,1384,1385],{},"        \u003C\u002FSetter.Value>\n",[47,1387,1388],{"class":190,"line":315},[47,1389,1390],{},"    \u003C\u002FSetter>\n",[47,1392,1393],{"class":190,"line":321},[47,1394,1219],{},[86,1396,1398],{"id":1397},"q4-性能问题","Q4: 性能问题？",[16,1400,1401,236,1403,1405,1406,1408],{},[19,1402,1284],{},[24,1404,30],{}," 需要运行时查找，比 ",[24,1407,105],{}," 稍慢",[16,1410,1411,236],{},[19,1412,1295],{},[41,1414,1415,1420],{},[44,1416,1417,1418],{},"只在需要主题切换的资源上使用 ",[24,1419,30],{},[44,1421,1422,1423],{},"固定资源（如颜色定义）使用 ",[24,1424,105],{},[33,1426],{},[36,1428,1430],{"id":1429},"相关链接","📚 相关链接",[41,1432,1433,1440,1447],{},[44,1434,1435],{},[47,1436,1437],{},[47,1438,1439],{},"WPF资源系统",[44,1441,1442],{},[47,1443,1444],{},[47,1445,1446],{},"DynamicResource与StaticResource",[44,1448,1449],{},[47,1450,1451],{},[47,1452,1453],{},"ResourceDictionary使用",[33,1455],{},[36,1457,1459],{"id":1458},"最佳实践","🎨 最佳实践",[238,1461,1462,1476,1482,1488],{},[44,1463,1464,1467,1468,1471,1472,1475],{},[19,1465,1466],{},"统一命名","：主题文件使用统一的命名规范（如 ",[24,1469,1470],{},"LightTheme.xaml","、",[24,1473,1474],{},"DarkTheme.xaml","）",[44,1477,1478,1481],{},[19,1479,1480],{},"资源层次","：颜色 → 画刷 → 样式，逐层引用",[44,1483,1484,1487],{},[19,1485,1486],{},"隐式样式","：使用隐式样式统一控件外观",[44,1489,1490,1493],{},[19,1491,1492],{},"测试覆盖","：确保所有页面和控件在主题切换后正常显示",[33,1495],{},[1497,1498,1499],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":185,"searchDepth":197,"depth":197,"links":1501},[1502,1503,1507,1513,1517,1523,1529,1530],{"id":38,"depth":197,"text":39},{"id":21,"depth":197,"text":84,"children":1504},[1505,1506],{"id":88,"depth":203,"text":89},{"id":177,"depth":203,"text":178},{"id":258,"depth":197,"text":259,"children":1508},[1509,1510,1511,1512],{"id":262,"depth":203,"text":263},{"id":416,"depth":203,"text":417},{"id":605,"depth":203,"text":606},{"id":669,"depth":203,"text":670},{"id":776,"depth":197,"text":777,"children":1514},[1515,1516],{"id":780,"depth":203,"text":781},{"id":1066,"depth":203,"text":1067},{"id":1132,"depth":197,"text":1133,"children":1518},[1519,1520,1521,1522],{"id":1136,"depth":203,"text":1137},{"id":1169,"depth":203,"text":1170},{"id":1222,"depth":203,"text":1223},{"id":1248,"depth":203,"text":1249},{"id":1274,"depth":197,"text":1275,"children":1524},[1525,1526,1527,1528],{"id":1278,"depth":203,"text":1279},{"id":1301,"depth":203,"text":1302},{"id":1334,"depth":203,"text":1335},{"id":1397,"depth":203,"text":1398},{"id":1429,"depth":197,"text":1430},{"id":1458,"depth":197,"text":1459},"md",{},"\u002Fcsharp\u002Fwpf\u002F基于资源字典实现主题切换",{"title":5,"description":185},"csharp\u002FWPF\u002F基于资源字典实现主题切换","fESHRmvlL7cJizLaaFdmm-Vt08q71pnATLRvRkQ92Zs",1791042466348]