7

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!!

NaiveCoder
  • 97
  • 2
  • 6

2 Answers2

6

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.

Evk
  • 98,527
  • 8
  • 141
  • 191
0

1. maybe priority of declaration is wrong

It may be useful: can-merged-resource-dictionaries-access-resources-from-app-xaml


2. Another way

i think this is good to define color in a page:

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

then bind buttons foreground to those page color resource:

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

and in a resource dictionary, binding every Property youe need to that:

<Setter Property="Property" Value="{TemplateBinding Foreground}"/>
Javad Ebrahimi
  • 333
  • 5
  • 13
  • thx! But I believe solution 1 will only work for UWP(although I've not tested it). As to 2, I don't want to use dynamic resource. There're many styles in my App.xaml, and I want to move them out to separate resource dictionaries, so I really want to get my method to work. – NaiveCoder Jun 10 '17 at 10:08
  • link may be helpful: [Adding a Merged Dictionary to a Merged Dictionary](https://stackoverflow.com/questions/3419543/adding-a-merged-dictionary-to-a-merged-dictionary/4113594#4113594) – Javad Ebrahimi Jun 10 '17 at 10:41
  • Full description at: [Static resource shared in merged dictionaries](https://stackoverflow.com/questions/4325015/static-resource-shared-in-merged-dictionaries) – Javad Ebrahimi Jun 10 '17 at 10:45
  • In fact, base on Evk's answer, I moved 'MyColor' to another resource dictionary and merged it in App.xaml(before Dictionary1.xaml), then everything it worked. This is like the solution 1, but you failed to mention why and how it works, so I can not mark this answer as accepted. Sorry! But thanks! – NaiveCoder Jun 10 '17 at 13:07