Wpf 引用包含合并词典的资源词典时出现问题

Wpf 引用包含合并词典的资源词典时出现问题,wpf,xaml,themes,resourcedictionary,Wpf,Xaml,Themes,Resourcedictionary,我有一个库,CommonLibraryWpfThemes,其中有几个资源字典XAML文件。My Themes/Generic.xml文件包含一个ResourceDictionary.MergedDictionaries声明,该声明将所有其他文件合并在一起 Generic.xaml <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="htt

我有一个库,CommonLibraryWpfThemes,其中有几个资源字典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>
如果我直接将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
            Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
    </Application.Resources>
</Application>
<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>


也许我做得不对。我的目标是使引用多个应用程序中的所有主题资源变得容易,而不必列出所有单独的文件。有推荐的方法吗?(注意:我没有尝试在多个主题之间切换——我只有一个主题。)

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

谢谢

编辑:

我尝试将ResourceDictionary包装到ResourceDictionary.MergedDictionary元素中,但也没有成功(我得到了相同的错误):


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

(为清晰起见进行编辑)

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

失败的原因是什么

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

对于其他自定义笔刷等,需要显式引用这些资源


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

检查App.xaml.cs calls InitializeComponent()中的构造函数-这就是合并资源字典的原因…

我的解决方案是,单击变通方法。

前面回答了类似的问题,见问题

这是一个优化错误,请参阅:

论建筑中每一个对象的创造 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>   

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

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

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

因此,我认为您是说直接在App.xaml中引用ResourceDictionary是必要的,也是唯一可行的方法。也就是说,我不可能“预合并”所有词典,而只是引用App.xaml中的预合并实体。没有那么方便,但如果这就是它的工作原理,那就不是世界末日。到目前为止,我总是使用
{StaticResource MyResourceName}
显式设置我的样式属性,所以我想我必须重构很多东西来利用Generic.xaml允许的默认行为。我有这个权利吗?当您将字典与app.xaml合并时,您将使整个应用程序都可以访问资源“全局”(如名称所示)。app.xaml中的资源不需要通过字典名引用,只需要通过特定的资源键引用,我可能对此不清楚,我将澄清答案。我通常为应用程序的不同部分创建分组合并词典,并根据需要在xaml中引用该词典。感谢您澄清您的答案,但我可能误解了您所说的“将其包装在
MergedDictionary
包装器中”的意思,或者这也不起作用。我用一个代码示例在问题的底部进行了编辑。是的,你做得对,尽管我不知道为什么它不起作用。可能是一些与generic.xaml直接相关的bug。尝试将其他一些字典合并到同一个位置,并使用其中的一些资源,看看它是否有效。如果我将代码粘贴到不同的文件(MergedDictionary.xaml)中也不起作用:(这对我很有帮助。我试图找出我的页面(托管在框架中)的原因)我们没有获得在我的App.xaml中定义的资源。结果发现构造函数没有调用InitializeComponent。谢谢Chris!!!!我将在这里开始一个小奖励。将几个ResourceDictionary组合成一个主题(并在App.xaml中加载)这似乎是一种很常见的情况…该错误似乎只出现在较旧版本的.NET 4:4.0.30319.1008中。我在XP和一些未更新的Windows 7安装中看到过这种情况。指向microsoft connect的链接因以下原因被否决:链接没有链接文本;没有任何解释;外部内容-无法控制内容。
<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>   
        MyApplication.App app = new MyApplication.App();
        app.InitializeComponent();