无法引用包含合并字典的资源字典

时间:2009-08-04 19:18:57

标签: wpf xaml themes resourcedictionary

我有一个库,CommonLibraryWpfThemes,里面有几个Resource Dictionary XAML文件。 My 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 - FAILS

<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 - SUCCEEDS

<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.MergedDictionary元素中包装ResourceDictionary,但这也不起作用(我得到相同的错误):

<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>

5 个答案:

答案 0 :(得分:67)

先前在这里回答了类似的问题,请参阅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>   

答案 1 :(得分:12)

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

答案 2 :(得分:4)

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

(为清晰起见编辑)

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

失败的原因

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

是因为你没有将它包装在MergedDictionary包装器中,而是将其添加到合并的词典中。直接添加到资源仅适用于您在本地声明的资源,例如风格等等。

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

另请注意,样式不必在generic.xaml中具有“默认样式”行为 - 如果可以访问具有等于元素类型的键的样式(全局或本地资源),则它将使用样式作为默认样式。 generic.xaml只是一种便利。

检查this回答。

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

您还应该检查WindowDictionary.xaml的内容,此错误有一定的气味。

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:-1)

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