Reputation: 97
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!!
Upvotes: 7
Views: 6794
Reputation: 101473
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.
Upvotes: 6
Reputation: 359
It may be useful: can-merged-resource-dictionaries-access-resources-from-app-xaml
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}"/>
Upvotes: 0