感谢 Abe 的帮助,尽管最后我使用了一个“解析器”类,该类作为合并字典包含并解析为适当的主题字典。原因超出了他原始问题的范围:
- 您可以在初始化阶段加载适当的字典,
App.xaml.cs
而无需稍后根据用户选择以编程方式覆盖资源(在您必须合并默认主题之前,例如初始化时的 Light,如果用户选择了 Dark 然后合并稍后的黑暗主题)
- 最重要的是,如果您稍后覆盖主题资源,那么在初始化时定义的引用被覆盖资源的其他资源将不会改变!
该代码基于此博主的想法。
ThemeResourceDictionaryResolver.cs
using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Resources;
using System.IO.IsolatedStorage;
namespace YourAppName.View
{
public enum ApplicationTheme
{
Dark,
Light
}
public class ThemeResourceDictionaryResolver : ResourceDictionary
{
public ThemeResourceDictionaryResolver() : base()
{
ApplicationTheme theme;
if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
// Set here which dictionary you want to be loaded in Blend
theme = ApplicationTheme.Light;
}
else
{
ApplicationTheme theme;
if (!IsolatedStorage.ApplicationSettings.TryGetValue("ApplicationTheme", out theme))
{
// The 'standard' way to get the global phone theme
Visibility darkBGVisibility = (Visibility)Application.Current.Resources["PhoneDarkThemeVisibility"];
theme = (darkBGVisibility == Visibility.Visible) ? ApplicationTheme.Dark : ApplicationTheme.Light;
}
}
// Change the URI string as appropriate - this way refers to the Dictionaries
// which are set to 'Build: Page'. I couldn't get to work when set to Build as
// Content and using the simpler URI scheme.
Uri uri = new Uri(string.Format("YouAppName;component/View/Themes/{0}ThemeResourceDictionary.xaml", theme), UriKind.RelativeOrAbsolute);
ResourceDictionary res = this.LoadXaml<ResourceDictionary>(uri);
this.MergedDictionaries.Add(res);
}
// For some reason a simple ResourceDictionary() { Source = uri }; does not work,
// need to use this instead
T LoadXaml<T>(Uri uri)
{
StreamResourceInfo info = Application.GetResourceStream(uri);
if (info != null)
{
using (StreamReader reader = new StreamReader(info.Stream))
{
return (T)XamlReader.Load(reader.ReadToEnd());
}
}
return default(T);
}
}
}
MainResourceDictionary.xaml
...
<ResourceDictionary.MergedDictionaries>
<views:ThemeResourceDictionaryResolver />
</ResourceDictionary.MergedDictionaries>
<!-- StaticResources that refer to the theme StaticResources can go here -->
...
应用程序.xaml
...
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="View/Themes/MainResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
...