XAML ResourceDictionary 无法使用单个键集正确加载

XAML ResourceDictionary not loading correctly with a single keyset

我一直在开发 WPF 应用程序,遇到了一些与我的 App.XAML 文件的 Application.Resources 元素中定义的资源有关的奇怪行为。

我真的只需要在我的 ResourceDictionary 中定义一个字符串资源,我尝试使用以下 XAML:

<Application x:Class="MyClass.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <Application.Resources>
        <sys:String x:Key="htmlHelpFilePath">.\Help\glossary.chm</sys:String>
    </Application.Resources>
</Application>

然后尝试使用以下代码访问它:

ResourceDictionary resourceDictionary = App.Current.Resources;
string htmlHelpFile = (string)resourceDictionary["htmlHelpFilePath"];

不幸的是,这导致 htmlHelpFile 被设置为空。调试器还显示 resourceDictionary 有零个键集。

我开始尝试,发现只需将另一个资源添加到我的 Application.Resource XAML 元素中就可以正确填充字典,所以我最终选择了:

<Application.Resources>
    <sys:String x:Key="htmlHelpFileName">glossary.chm</sys:String>
    <sys:String x:Key="htmlHelpFileDirectory">.\Help\</sys:String>
</Application.Resources>

此解决方案按预期工作,我继续我的工作,但我完全不明白为什么这种行为会以其发生的方式发生。我对 XAML 配置的 WPF 应用程序的内部工作原理的了解非常基础,很想知道这种奇怪行为的原因。

这是一个已知错误。 Ben Gribaudo 在他的博客上写了关于这个问题的文章 (link to full blog post)。引用此post中的相关位:

[...]

In the program’s App.xaml file:

  • The <Application> tag does not have a StartupUri attribute. (Instead, the program’s initial window is launched by an override of Application’s OnStartup method in App.xaml.cs.)
  • <Application.Resources> contains only one entry.

[...]

Visual Studio auto-generates a hidden file named App.g.cs which “wires” App.xaml into the application. When the above-mentioned two factors are present, the code generator sometimes fails to insert the code that loads <Application.Resources>’s contents into the application. If this loading does not occur, other XAML files in the program will be unable to use the resources defined in <Application.Resources>.

(强调我的)

Microsoft Connect 也有这个问题的记录(link);但是负责的开发团队已将其声明为 "won't fix".

还有一个 Whosebug 问题,其中包含许多讨论不同可能解决方法的答案:App.xaml file does not get parsed if my app does not set a StartupUri?

您自己发现的一种变通方法——通过简单地添加第二个(虚拟)资源来避免在资源字典中只有一个资源。