StaticResource reference inside DataTemplate

I came across some weird behavior referring to StaticResources from the DataTemplate defined in ResourceDictionary.

In this example, I populate the list with numbers 1 through 9 using the DataTemplate defined in ResourceDictionary.

Here is 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> 

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

StaticResource CoolNumbersColor defined in App.xaml along with ResourceDictionary1.xaml . Here is 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 see the expected behavior in the designer of Visual Studio 2010. Indeed, a colored list of numbers appears. But when I try to run this sample, I get an error

"Cannot find resource named CoolNumbersColor. Case sensitive"

I do not understand why this is happening. CoolNumbersColor score CoolNumbersColor delayed somehow? Lexically, it is in front of a unified resource.

The only way to make this work (other than using DynamicResources) is to create a second ResourceDictionary (for example, ResourceDictionary2.xaml), define CoolNumbersColor there and merge them all into ResourceDictionary.MergedDictionaries as follows:

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

+6
source share
1 answer

I assume this is due to the fact that a:

StaticResource

  • Doesn't support direct links
  • It is installed only once at program startup: search for resources by load time

DynamicResource

  • Supports direct links
  • Applies to each access to the resource: view at runtime

Example of forward reference

Doesn't 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 of launching the CoolNumbersColor (StaticResource) application, which is not available in the "visibility" of the DataTemplate , accordingly, it throws an exception, it tries to find it in its area, but cannot find it.

When using resource dictionaries, they are loaded first, respectively, in this case, this will be the only viewing area in which the resource is present.

DynamicResource will not load when the application starts, it will be loaded during its first request, and at this stage of the DataTemplate it β€œsees” the resource.

The question remains: Why this trick works in the Studio? . There may be a difference between loading at run time and in development mode, but I have not found official confirmation in the documentation or elsewhere.

+6
source

All Articles