在WPF中,如何从合并的字典中引用App.xaml中的StaticResource?

7
这似乎是一个老问题:为什么我无法从合并的字典中引用App.xaml中的StaticResource?以下是我的代码:
App.xaml:
<Application x:Class="WpfResources.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="MyColor">GreenYellow</Color>

            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>

    </Application.Resources>
</Application>

Dictionary1.xaml:

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

    <SolidColorBrush x:Key="Button.Static.Foreground" Color="{StaticResource MyColor}"/>

    <Style TargetType="{x:Type Button}">
        <Setter Property="Foreground"
            Value="{StaticResource Button.Static.Foreground}"/>
    </Style>
</ResourceDictionary>

在设计时,一切都很好,我可以看到按钮的前景设置为 MyColor。但在运行时,我遇到了以下问题:

异常:找不到名为 'MyColor' 的资源。资源名称区分大小写。

顺便说一句:这些代码在 UWP 中可以工作,但在 WPF 中似乎有所改变。我在网上做了很多搜索,但没有找到答案。

非常感谢任何想法!谢谢!

(顺便说一句:我不想改为 DynamicResource 解决方案)

编辑: 为什么有人给我打低分?有什么好的理由吗? 虽然这是一个“旧”的问题,但根据我的搜索,它仍然没有适当的答案!!

2个回答

6
似乎问题出在XAML解析器构造应用程序的顺序上。首先,它会填充MergedDictionaries。为了做到这一点,它需要构建Dictionary1.xaml,但此时会失败,因为还没有带有MyColor键的资源。您可以通过在代码中以正确的顺序自己填充资源来验证这一点。请注意保留HTML标记。
this.Resources = new ResourceDictionary();
this.Resources.Add("MyColor", Colors.GreenYellow);
this.Resources.MergedDictionaries.Add(new ResourceDictionary() {Source = new Uri("Dictionary1.xaml", UriKind.Relative)});

现在它将正常工作。

当然,在代码中这样做不是一个选项(只是为了确认问题的来源)。作为一种解决方法,您可以这样做:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                <Color x:Key="MyColor">GreenYellow</Color>
            </ResourceDictionary>
            <ResourceDictionary Source="Dictionary1.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

现在 XAML 解析器将首先将您的字典与资源合并,然后再合并所有其他字典,因此 MyColor 将对它们所有人都可用。

4
这是我想要的答案!但愿我早点看到这个答案!非常感谢,先生,您救了我的命! - NaiveCoder
1
:) 非常不明显的解决方案。WPF 设计师是坏人。 - Stepagrus

0

1. 可能声明的优先级有误

这可能会有用:可以合并的资源字典是否可以访问来自app.xaml的资源


2. 另一种方式

我认为在页面中定义颜色的方法不错:

<SolidColorBrush x:Key="MyColor" Color="#fff"/>

然后将按钮前景绑定到那些页面颜色资源:

<Button Foreground="{DynamicResource MyColor}"/>

在一个资源字典中绑定你需要的每个属性。
<Setter Property="Property" Value="{TemplateBinding Foreground}"/>

谢谢!但我相信解决方案1只适用于UWP(尽管我还没有测试过)。至于第2个问题,我不想使用动态资源。我的App.xaml中有很多样式,我想将它们移到单独的资源字典中,所以我真的希望我的方法能够奏效。 - NaiveCoder
以下是有关编程的内容翻译,仅返回翻译后的文本:链接可能会对您有所帮助:将合并字典添加到合并字典中 - Javad Ebrahimi
完整描述在:静态资源共享于合并字典 - Javad Ebrahimi
事实上,根据Evk的答案,我将'MyColor'移动到另一个资源字典中,并在App.xaml(Dictionary1.xaml之前)中合并它,然后一切都正常工作了。这就像解决方案1,但是您没有提及为什么以及如何工作,因此我无法将此答案标记为已接受。抱歉!但是谢谢! - NaiveCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接