10

我目前正在研究可以动态应用于我的应用程序的样式和模板字典。在这种“新的”动态行为之前,我有几个资源字典,每个样式控件一个,我合并到 App.xaml 中:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ColorsDictionary.xaml"/>
            <ResourceDictionary Source="ControlsTemplatesDictionary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

现在,我希望我的应用程序具有样式,因此我决定将我以前的所有资源合并到一个名为“MyFirstTemplates”的新资源中,并仅将这个字典添加到 App.xaml。

新字典“MyFirstTemplates.xaml”:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">"
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ColorsDictionary.xaml"/>
        <ResourceDictionary Source="ControlsTemplatesDictionary.xaml"/>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

新的 App.xaml:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="MyFirstTemplates.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <Style TargetType="{x:Type Window}"/>
    </ResourceDictionary>
</Application.Resources>

注意:Window的默认样式是为了更正 WPF 4 的一个错误,请参阅将合并字典添加到合并字典

现在我已经进行了这个更改,我不能再将“ColorsDictionary.xaml”中的颜色资源用作 ControlsTemplateDictionary.xaml”中的静态资源。如果我改回在 app.xaml 中合并这些文件,一切正常。为了使其工作,我必须将这些StaticResource更改为DynamicResource。你知道为什么这不再起作用了吗?

谢谢 :-)

4

2 回答 2

10

通过将字典移出 App.xaml,在加载 MyFirstTemplates.xaml 期间,每个字典中的资源不在另一个资源树中。您的原始设置首先加载了 ColorsDictionary,然后在加载时可通过 App 资源访问 ControlsTemplatesDictionary。在您的新设置中,为了使颜色资源在 App 资源中可用,它需要通过 MyFirstTemplates 加载,这又需要加载两个字典,而这又需要访问颜色资源......所以它有点像无法静态解析的无限循环引用。DynamicResource 可以等到所有内容都加载完毕,然后毫无问题地访问颜色。

要修复使用 Dynamic 或将 ColorsDictionary 直接合并到 ControlsTemplatesDictionary。

于 2010-12-01T16:48:02.337 回答
2

约翰的回答很好,解释了为什么会这样。所以问题是在合并字典中使用合并字典时,内部字典不能“使用”彼此作为静态资源。

基本解决方案:

  • 使用动态资源
  • 使用StaticResource时仅使用来自 App.xaml 的单一层次结构

这两种解决方案都有问题。DynamicResource 存在性能问题。第二个解决方案限制了您组织 XAML 资源的方式。

替代解决方案:

我创建了一个简单的小程序(下面在 GitHub 中提供),它将作为预构建事件运行并将 XAML 文件从一个文件夹合并到一个长的 .XAML 文件中。好吧,它们需要具有不同的扩展名(.txaml),否则它们将被编译。

这允许您根据需要构建资源文件夹和文件,而不受 WPF 的限制。StaticResource 和设计器将始终工作。

GitHub 中的代码包含一个包含合并程序的简单解决方案。它将 2 个文件夹合并为 2 个文件。一个用于 App.xaml 资源,另一个用于 Generic.xaml 资源。“控件”项目中的 .xaml 文件(还有“主”项目)。

博客文章解释了这一点

于 2017-01-22T13:16:21.780 回答