Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.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
Wpf 如何在以编程方式添加到App.Current.Resources.MergedDictionaries集合的资源字典中应用样式?_Wpf_Silverlight_Mef_Silverlight 5.0 - Fatal编程技术网

Wpf 如何在以编程方式添加到App.Current.Resources.MergedDictionaries集合的资源字典中应用样式?

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

我正在使用一个非常大的Silverlight 5应用程序,它需要实现主题化。不幸的是,我不能使用C1(组件一)或Silverlight工具包主题机制,因为我必须实现大量xaml和代码更改。我被迫做一些开箱即用的事情

作为一个起点,我通过引用@Scott Whitlock编写的post on Stack Overflow创建了一个演示项目。这篇文章描述了如何动态加载Silverlight/WPF资源字典,并将其添加到Silverlight/WPF应用程序中的
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,这都应该有效