DataTemplate中的StaticResource引用

The*_*hos 7 wpf xaml datatemplate staticresource

从ResourceDictionary中定义的DataTemplate内部引用StaticResources时,我遇到了一些奇怪的行为.

在这个例子中,我使用ResourceDictionary中定义的DataTemplate填充数字1到9的列表框.

这是MainWindow.xaml代码:

<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>
Run Code Online (Sandbox Code Playgroud)

NumberTemplate在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>
Run Code Online (Sandbox Code Playgroud)

StaticResource CoolNumbersColor在App.xaml中定义ResourceDictionary1.xaml.这是我的App.xaml文件:

<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>
Run Code Online (Sandbox Code Playgroud)

首先,我可以在Visual Studio 2010设计器中看到预期的行为.确实会出现一个彩色的数字列表.但是在尝试运行此示例时,我收到错误

"找不到名为'CoolNumbersColor'的资源.资源名称区分大小写"

我不明白为什么会这样.CoolNumbersColor评估是否以某种方式推迟?从词汇上讲,它位于合并的resourcedictionary之前.

使这项工作的唯一方法(除了使用DynamicResources)是创建第二个ResourceDictionary(例如ResourceDictionary2.xaml),CoolNumbersColor在那里定义并将它们全部合并为ResourceDictionary.MergedDictionaries:

<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>
Run Code Online (Sandbox Code Playgroud)

Ana*_*aev 7

我想这是因为a:

StaticResource

  • 不支持前向引用
  • 程序启动时只设置一次:资源的加载时查找

DynamicResource

  • 支持前向引用
  • 适用于对资源的每次访问:运行时查找

Example of forward reference

不适用于StaticResource:

<Window x:Class="SeveralResourceDictionariesHelp.MainWindow"
        Background="{StaticResource testColor}" ... >

<Window.Resources>
    <SolidColorBrush x:Key="testColor">Red</SolidColorBrush>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

使用DynamicResource:

<Window x:Class="SeveralResourceDictionariesHelp.MainWindow"
        Background="{DynamicResource testColor}" ... >

<Window.Resources>
    <SolidColorBrush x:Key="testColor">Red</SolidColorBrush>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

在启动应用程序时,CoolNumbersColor(StaticResource)在"visibility"的"visibility"中不可用DataTemplate,它会抛出异常,他试图在其范围内找到它但无法找到它.

当使用资源字典时,它们分别被加载到第一个队列中,在这种情况下,将是资源存在的单个视图范围.

DynamicResource在启动应用程序时不会加载,它将在第一次请求时加载,在此阶段DataTemplate它"看到"资源.

问题仍然存在:Why this trick works in the Studio?.也许在运行时加载和设计模式之间存在差异,但我没有在文档或其他地方找到官方确认.

  • @Theodore Zographos:在WPF中,元素首先从其资源部分查找资源,然后冒泡到元素树的根,最后到达系统主题,以下序列说明顺序:1.元素层次结构.2. Application.Resources 3.输入主题4.系统主题. (2认同)
  • @Theodore Zographos:是的,确实如此.App.xaml中的字典按第一顺序排列,其中可用的所有资源都是应用程序的全局资源. (2认同)