Wpf 如何在以编程方式添加到App.Current.Resources.MergedDictionaries集合的资源字典中应用样式?
我正在使用一个非常大的Silverlight 5应用程序,它需要实现主题化。不幸的是,我不能使用C1(组件一)或Silverlight工具包主题机制,因为我必须实现大量xaml和代码更改。我被迫做一些开箱即用的事情 作为一个起点,我通过引用@Scott Whitlock编写的post on Stack Overflow创建了一个演示项目。这篇文章描述了如何动态加载Silverlight/WPF资源字典,并将其添加到Silverlight/WPF应用程序中的Wpf 如何在以编程方式添加到App.Current.Resources.MergedDictionaries集合的资源字典中应用样式?,wpf,silverlight,mef,silverlight-5.0,Wpf,Silverlight,Mef,Silverlight 5.0,我正在使用一个非常大的Silverlight 5应用程序,它需要实现主题化。不幸的是,我不能使用C1(组件一)或Silverlight工具包主题机制,因为我必须实现大量xaml和代码更改。我被迫做一些开箱即用的事情 作为一个起点,我通过引用@Scott Whitlock编写的post on Stack Overflow创建了一个演示项目。这篇文章描述了如何动态加载Silverlight/WPF资源字典,并将其添加到Silverlight/WPF应用程序中的App.Current.Resource
App.Current.Resources.MergedDictionaries
集合中
我创建了4个项目。第一个是Silverlight 5应用程序本身,第二个、第三个和第四个是用于定义所有主题细节的Silverlight类库。每个类库都有一个入口点,它是ResourceDictionary
的派生类型
在AppStart事件上,应用程序加载默认的主题类库,该类库本质上是一块空白的石板,包含Silverlight中定义的所有默认样式。通过加载,我的意思是将类库中定义的DefaultTheme
资源字典添加到App.Current.Resources.MergedDictionaries
集合中
当用户从应用程序内的组合框中选择另一个主题时,代码将删除现有的默认主题,并将蓝色或红色或任何其他主题的入口点资源字典添加到app.Current.Resources.MergedDictionaries
集合中
但是,即使在发生此操作时没有抛出错误,样式本身也不会重新应用。我已经验证了每个主题在所有方面都具有相同的样式键
关于如何强制App.Current.RootVisual在“主题切换”后重新应用新添加的资源字典中的样式,您有什么想法吗
谢谢,在添加新的ResourceDictionary之前,请先尝试搜索当前ResourceDictionary并将其删除
string themeName = "White";
string oldThemeName = "Black";
string oldResourcePathString = String.Format("/Library.Name;component/Themes/{0}Theme.xaml", oldThemeName);
StreamResourceInfo sriOldTheme = Application.GetResourceStream(new Uri(oldResourcePathString, UriKind.Relative));
if (sriOldTheme != null)
{
StreamReader sr = new StreamReader(sriOldTheme.Stream);
object resourceObject = XamlReader.Load(sr.ReadToEnd());
ResourceDictionary resource = resourceObject as ResourceDictionary;
if (resource != null)
{
Application.Current.Resources.MergedDictionaries.Remove(resource);
}
}
string resourcePathString = String.Format("/Library.Name;component/Themes/{0}Theme.xaml", themeName);
StreamResourceInfo sriTheme = Application.GetResourceStream(new Uri(resourcePathString, UriKind.Relative));
if (sriTheme != null)
{
StreamReader sr = new StreamReader(sriTheme.Stream);
object resourceObject = XamlReader.Load(sr.ReadToEnd());
ResourceDictionary resource = resourceObject as ResourceDictionary;
if (resource != null)
{
Application.Current.Resources.MergedDictionaries.Add(resource);
}
}
我从未测试过代码,所以请检查拼写错误,但无论您是在App.xaml中设置ResourceDictionary,还是在MainPage.xaml.cs中以编程方式设置ResourceDictionary,这都应该有效