首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Silverlight共享MergedDictionaries

Silverlight共享MergedDictionaries
EN

Stack Overflow用户
提问于 2010-11-11 17:31:42
回答 4查看 2.7K关注 0票数 4

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

代码语言:javascript
复制
<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中只实例化一次?

EN

回答 4

Stack Overflow用户

发布于 2010-11-12 17:15:13

问题是silverlight似乎简化了资源字典的加载,使得多个字典可以并行加载。因此,当一个字典与另一个字典存在依赖关系时,该依赖关系可能不会及时准备好。

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

下面是一个可以添加到App.xaml.cs文件中的函数,用于“手动”加载资源字典:

代码语言:javascript
复制
    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之前,您可以使用如下代码:-

代码语言:javascript
复制
    LoadResource(new Uri"Assets/Styles/Common.xaml", UriKind.Relative));
    LoadResource(new Uri("Assets/Styles/TextBoxStyle.xaml", UriKind.Relative));

它不会像使用Source属性那样高效,但它可以工作。如果你有很多这样的字典,但只有很少的包含共享资源的“公共”字典,那么你可以使用这种技术只加载“公共”字典,然后使用:-

代码语言:javascript
复制
Resource.MergedDictionaries.Add(new ResourceDictionary() {Source = new Uri("Assets/Styles/TextBoxStyle.xaml", UriKind.Relative)});

对于彼此不相互依赖的其他字典。

票数 4
EN

Stack Overflow用户

发布于 2011-04-06 03:15:53

我能够调整在http://www.wpftutorial.net/MergedDictionaryPerformance.html上提出的解决方案,使其与Silverlight和VS设计器一起工作(还没有尝试混合)。我在这里有一篇关于它的博客(http://softnotes.wordpress.com/2011/04/05/shared-resourcedictionary-for-silverlight/)

代码语言:javascript
复制
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用法:

代码语言:javascript
复制
<ResourceDictionary.MergedDictionaries>
    <ui:SharedResourceDictionary Source="/my_assembly_name;component/Resources/Shared.xaml"/>
</ResourceDictionary.MergedDictionaries>
票数 1
EN

Stack Overflow用户

发布于 2013-03-07 22:06:05

如果加载时出错,请确保将Build Action设置为以下选项之一:

代码语言:javascript
复制
//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));

格雷格

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4152955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档