使用 x:静态指定数据模板键时将被忽略

本文关键字:静态 数据 使用 | 更新日期: 2023-09-27 18:36:07

我在使用DataTemplate键时遇到了奇怪的行为:当DataType通过x:Type指定,x:Key通过x:Static reference指定时,x:Key被忽略。我编写了示例应用程序来说明它。

XAML 资源:

<DataTemplate DataType="{x:Type wpfApplication1:TestDto}" x:Key="{x:Static wpfApplication1:DataKeys.TestDtoKey}" />
<DataTemplate x:Key="{x:Static wpfApplication1:DataKeys.TestDtoKey2}" />
<DataTemplate DataType="{x:Type wpfApplication1:TestDto}" x:Key="TestKey3" />
<DataTemplate DataType="wpfApplication1:TestDto" x:Key="{x:Static wpfApplication1:DataKeys.TestDtoKey4}" />

C#:

public class TestDto {}
public static class DataKeys
{
    public static string TestDtoKey = "TestKey";
    public static string TestDtoKey2 = "TestKey2";
    public static string TestDtoKey4 = "TestKey4";
}

启动应用程序,请参阅此处。资源.调试器中的键:

{DataTemplateKey(WpfApplication1.TestDto)}  object {System.Windows.DataTemplateKey}
"TestKey2"  object {string}
"TestKey3"  object {string}
"TestKey4"  object {string}

如您所见,在第一种情况下,x:Key 被忽略!

有人可以解释一下发生了什么吗?文档 (http://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype.aspx) 明确指出,设置 x:Key 会将资源键设置为您在其中指定的任何内容。

使用 x:静态指定数据模板键时将被忽略

对您的问题的简短回答是 - 是的,这是 WPF 框架中的一个错误。此处报告的错误。

更新 -

Microsoft已经接受了这是 XAML 编译器中的一个错误,他们没有解决这个问题。引自Microsoft -

这是 XAML 编译器中的一个问题 - 它生成 BAML 来描述 每个资源的键,通常基于 x:键(如果存在) 如果不是,则在数据类型上。当 x:Key 本身是间接的(在 您的情况,使用 x:Static),编译器选择数据类型键。 虽然选择基于 x:Static 的键可能更"正确", 更改此设置将引入兼容性问题。另外,因为 编译时出现问题,您必须重新编译应用程序才能看到 修复(生成不同的 BAML 流)。您的现有副本 应用程序将包含旧的 BAML 流,并且行为方式相同 就像现在一样在运行时。出于这个原因,我们决定不会 修复此问题。

x:Key 在这里不会被忽略,但在第一种情况下设置为 DataTemplateKey(WpfApplication1.TestDto)。不能在"资源"部分下声明没有键值的资源。

如您所见,该键在此处自动设置为DataTemplateKey(WpfApplication1.TestDto)

从 MSDN -

此属性与 样式类。将此属性设置为不带 指定 x:键,数据模板将自动应用于 该类型的数据对象。请注意,当您这样做时,将设置 x:键 隐 式。因此,如果为此数据模板分配一个 x:Key 值, 您正在覆盖隐式 x:Key,而数据模板不会 将自动应用。

不知何故,如果您bind x:Key with static value而不是硬编码字符串,它会defined as default template for that dataType,因此 key 设置为 DataTemplateKey(WpfApplication1.TestDto) .

您可以通过向仅设置数据类型的资源添加另一个数据模板来验证这一点,即

<DataTemplate DataType="{x:Type wpfApplication1:TestDto}"/> .

它可以很好地编译,但会抛出运行时错误

"项目已添加。输入字典: 添加的"DataTemplateKey(WpfApplication1.TestDto)"键: 'DataTemplateKey(WpfApplication1.TestDto)'"

我不会有所帮助,而是尝试将 {get;set;} 附加到类中的每个属性。WPF(即绑定)中的某些员工没有他们就无法工作。也许这里也是同样的故事...

public static class DataKeys
{
  public static string TestDtoKey { get { return "TestKey"; } set; }
  public static string TestDtoKey2 { get { return "TestKey2"; } set; }
  public static string TestDtoKey4 { get { return "TestKey4"; } set; }
}