wpf 无法引用包含合并字典的资源字典
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1229395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Trouble referencing a Resource Dictionary that contains a Merged Dictionary
提问by devuxer
I have a library, CommonLibraryWpfThemes, with several Resource Dictionary XAML files in it. My Themes/Generic.xml file contains a ResourceDictionary.MergedDictionaries declaration that merges all the other files together.
我有一个库 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>
In my application project, I have a reference to CommonLibraryWpfThemes, and I explicitly reference Generic.xml in my App.xaml file.
在我的应用程序项目中,我引用了 CommonLibraryWpfThemes,并且我在 App.xaml 文件中明确引用了 Generic.xml。
App.xaml -- FAILS
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>
This doesn't work. I get the following error when I run my app:
这不起作用。运行我的应用程序时出现以下错误:
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
If I place the contents of Generic.xaml into App.xaml directly, everything works fine:
如果我将 Generic.xaml 的内容直接放入 App.xaml 中,则一切正常:
App.xaml -- SUCCEEDS
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>
Maybe I'm going about this in the wrong way. My goal is to make it easy to reference all my theme resources from multiple applications without having to list out all the individual files. Is there a recommended way to do this? (Note: I'm not trying to switch between multiple themes--I just have one theme.)
也许我以错误的方式解决这个问题。我的目标是使从多个应用程序中引用我的所有主题资源变得容易,而不必列出所有单个文件。有没有推荐的方法来做到这一点?(注意:我不想在多个主题之间切换——我只有一个主题。)
As a bonus, it would be nice if someone could tell me how to reference resources in an external library without breaking the designer in Visual Studio.
作为奖励,如果有人能告诉我如何在不破坏 Visual Studio 中的设计器的情况下引用外部库中的资源,那就太好了。
Thanks.
谢谢。
EDIT:
编辑:
I tried wrapping the ResourceDictionary in a ResourceDictionary.MergedDictionary element, but that also didn't work (I get the same error):
我尝试将 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>
回答by Fredrik Hedblad
Answered a similar question here earlier, see Adding a Merged Dictionary to a Merged Dictionaryquestion.
之前在这里回答了一个类似的问题,请参阅将合并字典添加到合并字典问题。
This is an optimization bug, see Microsoft Connect / DefaultStyleKey style not found in inner MergedDictionaries:
这是一个优化错误,请参阅内部 MergedDictionaries 中未找到 Microsoft Connect / DefaultStyleKey 样式:
On the creation of every object in XAML, if a default style is present (i.e. style w/ a key of Type) that style should be applied. As you can imagine there are several performance optimizations to make that (implied) lookup a light weight as possible. One of them is that we don't look inside Resource Dictionaries unless they are flagged as “containing default Styles”. There is a bug: if all your default styles are nested in merged dictionaries three levels deep (or deeper) the top dictionary does not get flagged so the search skips it. The work around is to put a default Style to something, anything, in the root Dictionary.
在 XAML 中创建每个对象时,如果存在默认样式(即带有 Type 键的样式),则应应用该样式。可以想象,有几种性能优化可以使(隐含)查找尽可能轻量级。其中之一是我们不会查看资源字典内部,除非它们被标记为“包含默认样式”。有一个错误:如果您的所有默认样式都嵌套在三层深(或更深)的合并字典中,则顶部字典不会被标记,因此搜索会跳过它。解决方法是将默认样式放在根字典中的任何内容中。
So adding a dummy style to the root dictionary fixes this. Example
所以在根字典中添加一个虚拟样式可以解决这个问题。例子
<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>
回答by Chris
Check your constructor in App.xaml.cs calls InitializeComponent() - this is what merges the resource dictionaries...
检查 App.xaml.cs 中的构造函数调用 InitializeComponent() - 这就是合并资源字典的...
回答by Kenan E. K.
You should not have to reference generic.xaml
at all, it has built-in support. This however means that it provides default styling, which you do not set explicitly. Explicitly set styles/templates need to be attainable from explicitly referenced res dictionaries.
您根本不需要参考generic.xaml
,它具有内置支持。然而,这意味着它提供了默认样式,您没有明确设置。显式设置的样式/模板需要可以从显式引用的资源字典中获得。
(EDIT for clarity)
(为清楚起见编辑)
One exception to this is the App.xaml
, where defined resources become accessible by the whole app, without requiring to reference any specific resource dictionary. The resource itself, would have to be accessible by name.
一个例外是App.xaml
,其中定义的资源可供整个应用程序访问,而无需引用任何特定的资源字典。资源本身必须可以通过名称访问。
The reason why this fails
这失败的原因
<Application.Resources>
<ResourceDictionary
Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
</Application.Resources>
is, I think, because you didn't wrap it in a MergedDictionary
wrapper, adding it to merged dictionaries. Adding directly to resources works only for resources you declare locally, e.g. the styles, etc. themselves.
我认为是因为您没有将其MergedDictionary
包装在包装器中,而是将其添加到合并的字典中。直接添加到资源仅适用于您在本地声明的资源,例如样式等本身。
However, as I said before, you shouldn't have to merge generic.xaml
anywhere, maybe you should just refactor brushes and other resources used outside styles, and merge only those resources in app.xaml
.
然而,正如我之前所说,你不应该在generic.xaml
任何地方合并,也许你应该重构画笔和其他在样式之外使用的资源,并且只合并app.xaml
.
Also note that styles do not have to be in generic.xaml to have "default style" behaviour - if a style with key equal to the type of the element is accessible to it (globally, or in local resources), then it will use the style as a default style. The generic.xaml
is just a convenience.
另请注意,样式不必在 generic.xaml 中即可具有“默认样式”行为 - 如果键等于元素类型的样式可访问(全局或本地资源),则它将使用样式作为默认样式。这generic.xaml
只是一种方便。
Check thisanswer.
检查这个答案。
For other custom brushes, etc, you need to reference those resources explicitly.
对于其他自定义画笔等,您需要明确引用这些资源。
You should also check the contents of the WindowDictionary.xaml
, this error has a certain smell about it.
您还应该检查 的内容WindowDictionary.xaml
,这个错误有一定的味道。
回答by ouflak
I was getting this error in my unit tests and Chris' answer from above gave me the clue I needed. Basically on my first tested method, I put:
我在单元测试中遇到了这个错误,克里斯的回答给了我我需要的线索。基本上在我的第一个测试方法上,我把:
MyApplication.App app = new MyApplication.App();
app.InitializeComponent();
And suddenly it could find my template for my pages. Note: this does mean that you have to check to see if an instance of your App already exists if you are unit testing your App.cs as well.
突然间,它可以为我的页面找到我的模板。注意:这确实意味着如果您还在对 App.cs 进行单元测试,则必须检查您的应用程序的实例是否已经存在。