2

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

作为起点,我通过参考 Stack Overflow Using Mef to Import a WPF DataTemplate上由 @Scott Whitlock 编写的帖子创建了一个演示项目。该帖子描述了如何动态加载 Silverlight/WPF 资源字典并将其添加到App.Current.Resources.MergedDictionariesSilverlight/WPF 应用程序内的集合中。

我创建了 4 个项目。第一个是 Silverlight 5 应用程序本身,第二个、第三个和第四个是用于定义所有主题细节的 silverlight 类库。每个类库都有一个入口点,它是ResourceDictionary.

在 AppStart 事件中,应用程序加载默认主题类库,它本质上是一个白板,所有默认样式都在 Silverlight 中定义。通过加载我的意思是DefaultTheme类库中定义的资源字典被添加到App.Current.Resources.MergedDictionaries集合中。

当用户从应用程序的组合框中选择另一个主题时,代码会删除现有的默认主题并将蓝色或红色,或任何其他主题的入口点资源字典添加到App.Current.Resources.MergedDictionaries集合中。

但是,即使发生此操作时没有引发任何错误,样式本身也不会重新应用。我已经验证每个主题都具有相同的样式键。

关于如何App.Current.RootVisual在“主题切换”之后强制重新应用新添加的资源字典中的样式的任何想法?

谢谢,

4

1 回答 1

0

尝试先搜索当前的 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 以编程方式设置,这都应该有效

于 2014-07-30T18:28:02.943 回答