为什么此XAML合并资源配置在运行时失败?

时间:2014-09-13 20:16:50

标签: c# wpf xaml

我有以下App.xaml:

<Application
    x:Class="Genisyss.V2.Client.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Genisyss.V2.Client"
    ShutdownMode="OnExplicitShutdown">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="Resources/ShellResources.xaml" />
                <ResourceDictionary>
                    <local:AppBootstrapper
                        x:Key="bootstrapper" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

ShellResources.xaml看起来像这样:

<ResourceDictionary
    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"
    x:Class="Genisyss.V2.Client.Resources.ShellResources"
    x:ClassModifier="public">

    <ResourceDictionary.MergedDictionaries>

        <!-- EXTERNAL RESOURCES -->
        <ResourceDictionary
            Source="/Teton.Wpf;component/Themes/Generic.xaml" />
        <ResourceDictionary
            Source="Images.xaml" />
    </ResourceDictionary.MergedDictionaries>

    <!-- controls and templates defined, etc -->

</ResourceDictionary>

以这种方式配置,程序在运行时因“找不到资源”或“xaml解析异常”而失败。

如果我将App.xaml更改为包含外部资源,请执行以下操作:

<Application
    x:Class="Genisyss.V2.Client.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Genisyss.V2.Client"
    ShutdownMode="OnExplicitShutdown">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!-- NOTE ADDITION OF EXTERNAL RESOURCES -->
                <ResourceDictionary
                    Source="/Teton.Wpf;component/Themes/Generic.xaml" />

                <ResourceDictionary
                    Source="Resources/ShellResources.xaml" />
                <ResourceDictionary>
                    <local:AppBootstrapper
                        x:Key="bootstrapper" />
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

现在我的程序在运行时找到资源并且运行时没有错误。这给了什么?我认为合并资源的意义实际上是合并资源,所以你不需要在两个地方申报它们。

修改

将ShellResources.xaml中的Source属性更改为绝对包uri:

pack://application:,,,/Teton.Wpf;component/Themes/Generic.xaml

但这没有任何区别。

1 个答案:

答案 0 :(得分:0)

由于需要在资源文件中定义事物的顺序,此错误出现了。我有一个WPF控件项目,它定义了一些自定义控件并覆盖了几个内置控件的默认样式。

总而言之,我拥有在Generic.xaml文件中进一步定义的资源,并且它们被进一步访问 - 这是禁止的。资源显然只能以严格自上而下的方式解析一次。我的印象是,它们以两次或多次传递的方式解析,就像普通的c#源代码一样。

为避免发生这种情况,我们建议您在WPF控件项目中布置Generic.xaml

<!-- Shared resources like brushes and colors -->
<!-- DEFAULT control styles, e.g. <Style TargetType="{x:Type TextBox}"... -->
<!-- Control styles for custom controls that are defined in your project -->

感谢@Aybe推动我深入研究这个问题。