I've been experiencing some strange behaviour when referencing StaticResources from inside a DataTemplate defined in a ResourceDictionary.
In this example, I fill a listbox with the numbers 1 to 9, using a DataTemplate defined in a ResourceDictionary.
Here's the MainWindow.xaml code:
<Window x:Class="testResources.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="350">
<Grid>
<ListBox Width="100" ItemTemplate="{StaticResource NumberTemplate}">
<ListBox.ItemsSource>
<Int32Collection>1,2,3,4,5,6,7,8,9</Int32Collection>
</ListBox.ItemsSource>
</ListBox>
</Grid>
The NumberTemplate
is defined in ResourceDictionary1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="NumberTemplate">
<Grid Background="{StaticResource CoolNumbersColor}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="35" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Background="{StaticResource CoolNumbersColor}" Text="{Binding Mode=OneWay}" />
</Grid>
</DataTemplate>
The StaticResource CoolNumbersColor
is defined in App.xaml along with ResourceDictionary1.xaml
. Here's my App.xaml file:
<Application x:Class="testResources.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>
<SolidColorBrush x:Key="CoolNumbersColor">GreenYellow</SolidColorBrush>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ResourceDictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
First of all I can see the expected behaviour in Visual Studio 2010 designer. Indeed a colored list of numbers appears. But when trying to run this sample I receive the error
"Cannot find resource named 'CoolNumbersColor'. Resource names are case sensitive"
I can't understand why this happens. Is CoolNumbersColor
evaluation deferred somehow? Lexically, it is in front of the merged resourcedictionary.
The only way to make this work (other than using DynamicResources) is to create a second ResourceDictionary (e.g. ResourceDictionary2.xaml), define CoolNumbersColor
there and merge them all in ResourceDictionary.MergedDictionaries
like this:
<Application x:Class="testResources.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>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ResourceDictionary2.xaml" />
<ResourceDictionary Source="pack://application:,,,/ResourceDictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I guess this is due to the fact that a:
StaticResource
DynamicResource
Example of forward reference
Not work with StaticResource
:
<Window x:Class="SeveralResourceDictionariesHelp.MainWindow"
Background="{StaticResource testColor}" ... >
<Window.Resources>
<SolidColorBrush x:Key="testColor">Red</SolidColorBrush>
</Window.Resources>
Work with DynamicResource
:
<Window x:Class="SeveralResourceDictionariesHelp.MainWindow"
Background="{DynamicResource testColor}" ... >
<Window.Resources>
<SolidColorBrush x:Key="testColor">Red</SolidColorBrush>
</Window.Resources>
At the time the application is launched, the CoolNumbersColor
(StaticResource) not available within the "visibility" of DataTemplate
, respectively, it throws an exception, he tries to find it in its scope but can not find it.
When using resource dictionaries they are loaded into the first queue, respectively, in this case would be a single scope of view in which the resource is present.
DynamicResource
will not be loaded when the application is launched, it will be loaded during his first request to him and at this stage DataTemplate
it "sees" the resource.
The question remains: Why this trick works in the Studio?
. Perhaps there is a difference between loading at runtime and in design mode, but I have not found an official confirmation in the documentation or elsewhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With