1

WPF 文档建议MergedDictionaries如果您在 XAML 中加载两个,ResourceDictionaries则第二个加载的将能够引用第一个。Windows Phone 文档MergedDictionaries没有明确说明这一点,但我假设同样的规则适用。但是,以下内容在我的 Windows Phone App.xaml 中不起作用,

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="View/ThemeDictionaries/LightThemeResourceDictionary.xaml"/>
    <ResourceDictionary Source="View/ThemeDictionaries/MainResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>

调试说 MainResourceDictionary 行不能引用SubTitleTextColorLightThemeResourceDictionary 中定义的 - 我已经检查了引用的拼写。

这种类型的加载在 Windows Phone 中是不可能的吗?我该如何解决它?

4

2 回答 2

1

根据Silverlight 资源文档(比 WPF 文档更适用),此方案将不起作用。有两种方法可以解决这个问题:

  • 将第一个字典合并到第二个字典而不是应用程序的字典。
  • 创建一个附加属性,该属性List<ResourceDictionary>将手动将它们合并为一个巨人ResourceDictionary并将应用程序的资源设置为它。
于 2013-08-16T17:44:12.923 回答
1

感谢 Abe 的帮助,尽管最后我使用了一个“解析器”类,该类作为合并字典包含并解析为适当的主题字典。原因超出了他原始问题的范围:

  1. 您可以在初始化阶段加载适当的字典,App.xaml.cs而无需稍后根据用户选择以编程方式覆盖资源(在您必须合并默认主题之前,例如初始化时的 Light,如果用户选择了 Dark 然后合并稍后的黑暗主题)
  2. 最重要的是,如果您稍后覆盖主题资源,那么在初始化时定义的引用被覆盖资源的其他资源将不会改变!

该代码基于此博主的想法

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>

...
于 2013-08-18T18:37:48.313 回答