Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In WPF, how to reference a StaticResource in App.xaml from merged dictionary

Tags:

c#

wpf

xaml

uwp

This seems an old question: Why I can not reference StaticResource in App.xaml from a merged dictionary? Here is my code:

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>

At design time, everything is fine, I can see the foreground of button is set to MyColor. But at the run time, I got:

Exception: Cannot find resource named 'MyColor'. Resource names are case sensitive.

btw:these code work in UWP, but in WPF, something seems changed. I've done lots search on web and can not find an answer.

Any idea would be appreciated! thx!

(btw: I don't want to change to DynamicResource solution)

Edit: Why anyone give me a downgrade? any good reason? Although this is an 'old' question, but based on my search, it still has no proper answer!!

like image 225
NaiveCoder Avatar asked Oct 29 '22 06:10

NaiveCoder


1 Answers

The reason seems to be an order in which xaml parser constructs your Application. First it fills MergedDictionaries. To do that - it needs to construct Dictionary1.xaml, and at this point it fails, because there is no resource with key MyColor yet. To verify this, you can fill resources yourself in the correct order in code:

this.Resources = new ResourceDictionary();
this.Resources.Add("MyColor", Colors.GreenYellow);
this.Resources.MergedDictionaries.Add(new ResourceDictionary() {Source = new Uri("Dictionary1.xaml", UriKind.Relative)});

And now it will work fine.

Of course doing that in code is not an option (just to confirm the source of a problem). As a workaround, you can do this:

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

Now xaml parser will first merge your dictionary with resources and then all other dictionaries, so MyColor will be available to all of them.

like image 77
Evk Avatar answered Nov 15 '22 06:11

Evk