我有一个应用程序,允许用户根据外部xaml文件更改颜色方案。当用户单击包含主题名称的MenuItem时,将执行以下代码:
MenuItem mi = sender as MenuItem;
string executingDirectory = Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf("\\"));
string path = System.IO.Path.Combine(executingDirectory + "\\Themes", mi.Header.ToString() + ".xaml");
if (File.Exists(path))
{
using (FileStream fs = new FileStream(path, FileMode.Open))
{
ResourceDictionary dic = (ResourceDictionary)XamlReader.Load(fs);
Resources.MergedDictionaries.Clear();
Resources.MergedDictionaries.Add(dic);
}
}
这适用于大多数应用程序 - 我的所有资源画笔都会更改 - 但有一个例外。我有一个子控件,其背景颜色由使用转换器的值绑定确定。不过,我没有将颜色硬编码到转换器中,而是让转换器使用字符串常量作为画笔名称,然后从App.Current.Resources返回颜色:
Brush ret = Application.Current.Resources[brushToReturn] as Brush;
这里似乎发生的事情是Application.Current.Resources没有与窗口保持相同的资源集。我已经尝试将主题加载到Application.Current.Resources并从转换器中读取,但这似乎也不起作用。谁能告诉我我在这里缺少什么?有没有办法改变,例如,Application.Current.Resources并让它影响打开的窗口?
谢谢!
答案 0 :(得分:0)
如果没有看到所有代码,很难说,但检查Resources
属性不会自动检查合并的词典。此外,如果您要合并Window
级别的主题资源,那么它们根本不会处于应用程序级别。为了保持一致,您最好让转换器获取要转换的元素并使用FindResource
:
var frameworkElement = values[0] as FrameworkElement;
var resource = frameworkElement.FindResource("SomeKey") as Brush;
使用IMultiValueConverter
可能是您的最佳选择。或者,如果这太乱了,您可能会考虑编写一个可以满足您需要的标记扩展。