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

dev*_*xer 44 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>
Run Code Online (Sandbox Code Playgroud)

在我的应用程序项目中,我引用了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>
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

如果我直接将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>
Run Code Online (Sandbox Code Playgroud)

也许我会以错误的方式解决这个问题.我的目标是让您轻松地从多个应用程序中引用我的所有主题资源,而无需列出所有单个文件.有推荐的方法吗?(注意:我不是要在多个主题之间切换 - 我只有一个主题.)

作为奖励,如果有人能告诉我如何在外部库中引用资源而不破坏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>
Run Code Online (Sandbox Code Playgroud)

Fre*_*lad 67

之前回答了类似的问题,请参阅将合并字典添加到合并字典问题.

这是一个优化错误,请参阅内部MergedDictionaries中找不到的Microsoft Connect/DefaultStyleKey样式:

在XAML中创建每个对象时,如果存在默认样式(即具有Type的键的样式),则应该应用该样式.您可以想象,有几种性能优化可以使(隐含)查找尽可能轻量级.其中之一是我们不会查看资源字典,除非它们被标记为"包含默认样式".有一个错误:如果所有默认样式都嵌套在合并的字典中三个级别(或更深),则顶级字典不会被标记,因此搜索会跳过它.解决方法是在根词典中将默认样式放在某个东西上.

因此,在根字典中添加虚拟样式可以解决此问题.例

<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>   
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 12

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

  • 这对我很有帮助.我试图找出为什么我的页面(托管在一个框架中)没有获得我的App.xaml中定义的资源.事实证明,构造函数没有调用InitializeComponent.谢谢Chris !!!! (2认同)

Ken*_* K. 5

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

(为了清楚起见编辑)

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

失败的原因

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

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

然而,正如我之前所说,您不必generic.xaml在任何地方合并,也许您应该重构画笔和外部样式中使用的其他资源,并仅合并app.xaml.

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

检查这个答案。

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

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