Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有不同系统主题的WPF蒙皮_C#_.net_Wpf_Resourcedictionary_Implicit Style - Fatal编程技术网

C# 具有不同系统主题的WPF蒙皮

C# 具有不同系统主题的WPF蒙皮,c#,.net,wpf,resourcedictionary,implicit-style,C#,.net,Wpf,Resourcedictionary,Implicit Style,我们的WPF应用程序有几个UI皮肤,可以在运行时切换,并应用于特定的框架元素及其子元素皮肤是编译的xaml资源字典,存储在主题dll中,皮肤通过使用自定义皮肤管理器类和附加的依赖属性皮肤实现,这实际上是通过将皮肤的资源字典添加到目标FrameworkElement.Resources.MergedDictionaries来改变皮肤。皮肤字典包含具有TargetType=“SomeType”和BasedOn=“{StaticResource{x:Type SomeType}}”的样式,从而基于WP

我们的WPF应用程序有几个UI皮肤,可以在运行时切换,并应用于特定的框架元素及其子元素皮肤是编译的xaml资源字典,存储在主题dll中,皮肤通过使用自定义皮肤管理器类和附加的依赖属性皮肤实现,这实际上是通过将皮肤的资源字典添加到目标FrameworkElement.Resources.MergedDictionaries来改变皮肤。皮肤字典包含具有TargetType=“SomeType”和BasedOn=“{StaticResource{x:Type SomeType}}”的样式,从而基于WPF系统主题的隐式样式将此样式应用于SomeType的所有框架元素。这种方法非常有效,但在尝试将主题化引入应用程序时遇到了问题。

主题根据我们的定义,是一种定制皮肤,应用于整个应用程序+特定系统主题(经典、Luna、Royale、Aero、Aero2(又名Metro))。它是通过将相应的资源文件从系统dll(PresentationFramework.aero for aero主题的aero.normalcolor.xaml)加载到Application.Resources.MergedDictionaries来实现的。如果我们将皮肤添加到此resourcedictionary,它将被忽略,因此皮肤将应用于每个活动窗口。这也很好,但是我们在运行时切换主题时遇到了困难:
如果主题基于相同的系统主题,那么就没有问题了,否则我们会得到令人讨厌和不想要的行为:具有应用外观的框架元素不会改变其通过隐式样式引入的外观(例如,当royale主题更改为aero时,按钮不会更改其镀铬和填充),此外,如果我们尝试为皮肤和主题存储ResourceDictionary的唯一实例,那么当具有相同皮肤的主题在视觉上合并到同一主题中时,就会出现这种情况:如果我们尝试应用这些主题,则每次都会应用首先应用的主题(例如,如果theme1=royale+blueskin,theme2=aero+blueskin,则如果首先应用theme1,则在这两种情况下应用theme1和theme2都应用“royale”外观)

有没有可能克服这些问题并在运行时更改WPF隐式样式?或者我们没有注意到资源字典的WPF机制的一些重要细节?

如果我对第一个“皮肤”的问题理解正确的话即使在设置其他资源字典时也要应用,请先尝试清除合并的资源字典

例如,这里有许多与在运行时加载资源相关的主题

这表明:

ResourceDictionary dic = (ResourceDictionary)XamlReader.Load(fs);
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(dic);

我们以这里使用的方式使用MS.Win32.UXThemeWrapper类,成功地应用了特定的系统主题
通过更改WPF内部的实际系统主题并删除隐式样式的BasedOn声明。

皮肤行为实际上很好:我们并没有清除合并字典(因为我们保留的元素资源不是皮肤特定的),而是替换旧的资源字典(具有“源”属性(与以前的皮肤资源具有相同的uri)和新皮肤的资源字典。但是,即使我们出于测试目的清除了合并字典,它们的行为仍然相同。您可以发布您使用的代码以指向不同的皮肤并显示资源的设置方式吗?