【问题标题】:Trouble referencing a Resource Dictionary that contains a Merged Dictionary引用包含合并字典的资源字典时遇到问题
【发布时间】:2010-11-16 19:05:22
【问题描述】:

我有一个库 CommonLibraryWpfThemes,其中包含多个资源字典 XAML 文件。我的 Themes/Generic.xml 文件包含一个 ResourceDictionary.MergedDictionaries 声明,它将所有其他文件合并在一起。

Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

在我的应用程序项目中,我引用了 CommonLibraryWpfThemes,并在我的 App.xaml 文件中明确引用了 Generic.xml。

App.xaml -- 失败

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
    </Application.Resources>
</Application>

这不起作用。运行应用程序时出现以下错误:

System.Windows.Markup.XamlParseException occurred
  Message="Cannot find resource named '{_fadedOrangeBrush}'. Resource names are case sensitive.  Error at object 'System.Windows.Setter' in markup file 'CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml' Line 18 Position 13."
  Source="PresentationFramework"
  LineNumber=18
  LinePosition=13

如果我将 Generic.xaml 的内容直接放入 App.xaml 中,一切正常:

App.xaml -- 成功

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

也许我以错误的方式处理这个问题。我的目标是让从多个应用程序中引用我的所有主题资源变得容易,而不必列出所有单独的文件。有推荐的方法吗? (注意:我不想在多个主题之间切换——我只有一个主题。)

作为奖励,如果有人能告诉我如何在不破坏 Visual Studio 设计器的情况下引用外部库中的资源,那就太好了。

谢谢。

编辑:

我尝试将 ResourceDictionary 包装在 ResourceDictionary.MergedDictionary 元素中,但这也不起作用(我得到了同样的错误):

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

【问题讨论】:

  • 我将在这里开始一个小赏金。将几个 RessourceDictionaries 组合成一个主题(并在 App.xaml 中加载它)似乎是一个足够常见的场景......

标签: wpf xaml themes resourcedictionary


【解决方案1】:

您根本不必引用generic.xaml,它具有内置支持。然而,这意味着它提供了您没有明确设置的默认样式。显式设置的样式/模板需要可以从显式引用的字典中获得。

(为清楚起见编辑)

App.xaml 是一个例外,其中定义的资源可供整个应用程序访问,而无需引用任何特定的资源字典。资源本身必须可以通过名称访问。

失败的原因

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
</Application.Resources>

我认为是因为您没有将其包装在 MergedDictionary 包装器中,而是将其添加到合并字典中。直接添加到资源仅适用于您在本地声明的资源,例如样式等。

但是,正如我之前所说,你不应该在任何地方合并generic.xaml,也许你应该重构画笔和其他使用外部样式的资源,只合并app.xaml中的那些资源。

另请注意,样式不必在 generic.xaml 中才能具有“默认样式”行为 - 如果其键(全局或在本地资源中)可以访问具有与元素类型相同的键的样式,则它将使用该样式作为默认样式。 generic.xaml 只是为了方便。

检查this的答案。

对于其他自定义画笔等,您需要明确引用这些资源。

你也应该检查WindowDictionary.xaml的内容,这个错误有一定的味道。

【讨论】:

  • 所以我认为您是说直接在 App.xaml 中引用 ResourceDictionaries 是必要的,并且是唯一可行的方法。即,我无法“预合并”我所有的字典,而只能从 App.xaml 中引用预合并的实体。不那么方便,但如果它是这样工作的,它不是世界末日。到目前为止,我总是使用{StaticResource MyResourceName} 显式设置我的Styles 属性,所以我想我必须重构很多东西才能利用Generic.xaml 允许的默认行为。我有这个权利吗?
  • 当您将字典与 app.xaml 合并时,您使资源“全局”,可供整个应用程序访问(如名称所述)。 app.xaml 中的资源不需要通过字典名称来引用,只需要通过特定的资源键,我可能一直不清楚,我会澄清答案。我通常为应用程序的不同部分创建分组的合并字典,并根据需要在 xaml 中引用该字典。
  • 感谢您澄清您的答案,但要么我误解了您所说的“将其包装在 MergedDictionary 包装器中”的意思,要么这也不起作用。我使用代码示例在问题的底部进行了编辑。
  • 是的,你做对了,虽然我不知道为什么它不起作用。也许这是与 generic.xaml 直接相关的一些错误。尝试将其他字典合并到同一个地方并使用其中的一些资源,看看它是否有效。
  • 如果我将代码粘贴到不同的文件 (MergedDictionary.xaml) 中也不起作用:(
【解决方案2】:

检查 App.xaml.cs 中的构造函数调用 InitializeComponent() - 这是合并资源字典的内容...

【讨论】:

  • 这对我很有帮助。我试图弄清楚为什么我的页面(托管在框架中)没有获得我的 App.xaml 中定义的资源。事实证明,构造函数没有调用 InitializeComponent。谢谢克里斯!!!!
【解决方案3】:

我的解决方案是here,点击解决方法。

【讨论】:

  • 投了反对票:没有链接文本的链接;没有任何解释;外部内容 - 无法控制内容。
【解决方案4】:

之前在这里回答了一个类似的问题,请参阅Adding a Merged Dictionary to a Merged Dictionary 问题。

这是一个优化错误,见Microsoft Connect / DefaultStyleKey style not found in inner MergedDictionaries

关于每个对象的创建 XAML,如果存在默认样式 (即带有类型键的样式) 应该应用样式。尽你所能 想象一下有几种表现 进行优化(暗示) 查找尽可能轻的重量。一 其中一个是我们不向内看 资源字典,除非它们是 标记为“包含默认值 风格”。有一个错误:如果你的所有 默认样式嵌套在合并 字典深度三层(或 更深)顶级字典没有 被标记以便搜索跳过它。 解决方法是设置默认值 风格的东西,任何东西,在 根字典。

所以在根字典中添加一个虚拟样式可以解决这个问题。示例

<Application x:Class="MyApp.App"  
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
    <Application.Resources> 
        <ResourceDictionary> 
            <ResourceDictionary.MergedDictionaries> 
                <ResourceDictionary 
                    Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
                </ResourceDictionary.MergedDictionaries> 
            <!-- Dummy Style, anything you won't use goes --> 
            <Style TargetType="{x:Type Rectangle}" /> 
        </ResourceDictionary> 
    </Application.Resources> 
</Application>   

【讨论】:

  • 该错误似乎只存在于旧版本的 .NET 4 中:特别是 4.0.30319.1008。我在 XP 和一些未更新的 Windows 7 安装上看到过这种情况。
  • microsoft connect 的链接已失效
【解决方案5】:

我在单元测试中遇到了这个错误,而 Chris 从上面的回答给了我需要的线索。基本上在我的第一个测试方法上,我放了:

        MyApplication.App app = new MyApplication.App();
        app.InitializeComponent();

突然间,它可以为我的页面找到我的模板。注意:这确实意味着如果您也在对 App.cs 进行单元测试,则必须检查您的 App 的实例是否已经存在。

【讨论】:

    猜你喜欢
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    相关资源
    最近更新 更多