在运行时更改DynamicResource颜色值

我的目标是在Base主题中定义样式,并且能够通过使用ResourceDictionary将它们添加到彼此之上来覆盖Custom主题中的某些值。 我已经能够使用某些属性而不是其他属性显然是由于Freezable对象 ,颜色是不起作用的。 我认为更改ResourceDictionary中的Color值会起作用,但它不是:

MainWindow.xaml:

  

基地\ Base.xaml:

  

基地\ Colors.xaml:

 Red 

自定义\ Colors.xaml:

 Blue 

Theme.cs:

 foreach (ResourceDictEntry rde in changeList) { Application.Current.Resources .MergedDictionaries .ElementAt(rde.dicIndex)[rde.key] = rde.value; } 

当我单步执行时,代码似乎正常工作我看到Color_Base的MergedDictionary条目从Red #FFFF0000更改为Blue #FF0000FF

但是,我的Grid的Background与DynamicResource PrimaryBackgroundColor绑定,不会从Red更改为Blue。

Snoop中没有显示错误; Grid.Background值将PrimaryBackgroundColor显示为Red(#FFFF0000)。

我错过了什么? 如何在运行时更改我的Color值?

完整代码这里有一个要点: https : //gist.github.com/dirte/773e6baf9a678e7632e6

编辑:

这看起来是最相关的: https : //stackoverflow.com/a/17791735/1992193但我认为样式的重点是在一个地方定义它并且让所有东西都使用它而不必修改后面的每个xaml /代码? 什么是最好的解决方案?

我知道一个解决方案是简单地将整个基本主题复制到自定义主题中,并且只加载您想要的主题,但是它需要在每个不需要的主题文件中管理每个属性。

我能够通过简单地将所有资源字典文件组合到代码中的单个资源字典中并应用最终的组合资源字典来制定解决方案。

 public static void ChangeTheme(string themeName) { string desiredTheme = themeName; Uri uri; ResourceDictionary resourceDict; ResourceDictionary finalDict = new ResourceDictionary(); // Clear then load Base theme Application.Current.Resources.MergedDictionaries.Clear(); themeName = "Base"; foreach (var themeFile in Util.GetDirectoryInfo(Path.Combine(ThemeFolder, themeName)).GetFiles()) { uri = new Uri(Util.GetPath(Path.Combine(ThemeFolder, themeName + @"\" + themeFile.Name))); resourceDict = new ResourceDictionary { Source = uri }; foreach (DictionaryEntry de in resourceDict) { finalDict.Add(de.Key, de.Value); } } // If all you want is Base, we are done if (desiredTheme == "Base") { Application.Current.Resources.MergedDictionaries.Add(finalDict); return; } // Now load desired custom theme, replacing keys found in Base theme with new values, and adding new key/values that didn't exist before themeName = desiredTheme; bool found; foreach (var themeFile in Util.GetDirectoryInfo(Path.Combine(ThemeFolder, themeName)).GetFiles()) { uri = new Uri(Util.GetPath(Path.Combine(ThemeFolder, themeName + @"\" + themeFile.Name))); resourceDict = new ResourceDictionary { Source = uri }; foreach (DictionaryEntry x in resourceDict) { found = false; // Replace existing values foreach (DictionaryEntry z in finalDict) { if (x.Key.ToString() == z.Key.ToString()) { finalDict[x.Key] = x.Value; found = true; break; } } // Otherwise add new values if (!found) { finalDict.Add(x.Key, x.Value); } } } // Apply final dictionary Application.Current.Resources.MergedDictionaries.Add(finalDict); } 

MainWindow.xaml:

  

Base.xaml:

  

基地\ Colors.xaml:

 Red 

自定义\ Colors.xaml:

 Blue