44

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

通用的.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>
4

5 回答 5

68

之前在这里回答了一个类似的问题,请参阅将合并字典添加到合并字典问题。

这是一个优化错误,请参阅内部 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>   
于 2010-11-12T15:46:46.457 回答
13

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

于 2010-01-19T11:20:20.703 回答
4

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

(为清楚起见进行编辑)

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

失败的原因

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

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

但是,正如我之前所说,您不应该在任何地方合并generic.xaml,也许您应该重构画笔和其他样式之外使用的资源,并仅将这些资源合并到app.xaml.

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

检查这个答案。

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

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

于 2009-08-04T19:32:53.617 回答
0

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

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

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

于 2012-11-20T08:31:27.877 回答
-1

我的解决方案在这里,单击解决方法。

于 2010-10-15T11:13:46.147 回答