4

我正在使用 Silverlight 4 并尝试分享一些常见的样式(颜色、画笔)。我的做法是将它们放入“Common.xaml”资源字典,然后在所有其他资源字典中使用它。像这样引用所有内容:

<Application 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="SampleApp.App"
>
  <Application.Resources>

    <ResourceDictionary>

      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Assets/Styles/Common.xaml"/>
        <ResourceDictionary Source="Assets/Styles/TextBoxStyle.xaml"/>
      </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

  </Application.Resources>

</Application>

问题是,我在 InitializeComponent 上收到一个异常,指出找不到常用样式(找不到具有名称/键的资源......)

我必须在我使用它的每个资源字典中明确引用“Common.xaml”......这基本上会导致“Common.xaml”中存在的每种颜色、画笔、模板和诸如此类的多个实例。

没有任何方法可以共享资源,因此只能在 Silverlight 中实例化一次吗?

4

4 回答 4

4

问题是silverlight 似乎简化了资源字典的加载,以便可以并行加载多个字典。因此,当一个字典依赖于另一个字典时,该依赖关系可能无法及时准备好。

由于ResourceDictionary没有内置方法来描述相互依赖关系,也没有事件来指示它何时加载,我能够找到的唯一解决方案是自己管理字典的加载。

这是您可以添加到 App.xaml.cs 文件以“手动”加载资源字典的功能:-

    private void LoadResource(Uri uri)
    {
        var info = Application.GetResourceStream(uri);
        string xaml;
        using (var reader = new StreamReader(info.Stream))
        {
            xaml = reader.ReadToEnd();
        }

        ResourceDictionary result = XamlReader.Load(xaml) as ResourceDictionary;

        if (result != null)
        {
            Resources.MergedDictionaries.Add(result);
        }
    }

现在在Application_Startup分配之前,RootVisual您将使用如下代码:-

    LoadResource(new Uri"Assets/Styles/Common.xaml", UriKind.Relative));
    LoadResource(new Uri("Assets/Styles/TextBoxStyle.xaml", UriKind.Relative));

它不会像使用该Source属性那样有效,但它会起作用。如果您有许多这样的字典并且只有少数包含共享资源的“通用”字典,那么您可以使用此技术仅加载“通用”字典,然后使用:-

Resource.MergedDictionaries.Add(new ResourceDictionary() {Source = new Uri("Assets/Styles/TextBoxStyle.xaml", UriKind.Relative)});

对于彼此没有相互依赖关系的其他字典。

于 2010-11-12T09:15:13.117 回答
1

我能够调整http://www.wpftutorial.net/MergedDictionaryPerformance.html提出的解决方案, 使其与 Silverlight 和 VS 设计器一起使用(尚未尝试过 Blend)。我在这里有一篇博文(http://softnotes.wordpress.com/2011/04/05/shared-resourcedictionary-for-silverlight/

public class SharedResourceDictionary : ResourceDictionary
{
    public static Dictionary<Uri, ResourceDictionary> _sharedDictionaries =
       new Dictionary<Uri, ResourceDictionary>();

    private Uri _sourceUri;
    public new Uri Source
    {
        get { return _sourceUri; }
        set
        {
            _sourceUri = value;
            if (!_sharedDictionaries.ContainsKey(value))
            {
                Application.LoadComponent(this, value);
                _sharedDictionaries.Add(value, this);
            }
            else
            {
                CopyInto(this, _sharedDictionaries[value]);
            }
        }
    }

    private static void CopyInto(ResourceDictionary copy, ResourceDictionary original)
    {
        foreach (var dictionary in original.MergedDictionaries)
        {
            var mergedCopy = new ResourceDictionary();
            CopyInto(mergedCopy, dictionary);
            copy.MergedDictionaries.Add(mergedCopy);
        }
        foreach (DictionaryEntry pair in original)
        {
            copy.Add(pair.Key, pair.Value);
        }
    }
}

XAML 用法:

<ResourceDictionary.MergedDictionaries>
    <ui:SharedResourceDictionary Source="/my_assembly_name;component/Resources/Shared.xaml"/>
</ResourceDictionary.MergedDictionaries>
于 2011-04-05T19:15:53.247 回答
0

如果加载时出错,请确保将构建操作设置为以下之一:

//In the dll, which is in the xap, marked as Build Action: Resource or Page
LoadResource(new Uri("SilverlightApplication48;component/GlobalAssets.xaml", UriKind.Relative));

//In the xap at the same level as the dll, (not in the dll) marked as Build Action: Content.
LoadResource(new Uri("Dictionary1.xaml", UriKind.Relative));

//In a separate library, marked as Build Action: Resource or Page.
LoadResource(new Uri("StylesLibrary;component/Dictionary2.xaml", UriKind.Relative));

格雷格

于 2013-03-07T14:06:05.093 回答
0

这个线程的另一个有趣的注释是,如果在两个不同的字典中找到一个样式,SL 只会保留一个副本。最后一个获胜。换句话说,如果您有两种不同的样式,它们都具有相同的键,则在加载第二个时会丢弃第一个。

于 2013-03-09T16:55:42.993 回答