首页 文章

使用x:Static指定时,将忽略DataTemplate键

提问于
浏览
12

我遇到了DataTemplate键的奇怪行为:当通过x:Type指定DataType时,x:通过x指定Key:静态引用,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";
}

启动应用程序,请参阅this.Resources.Keys在调试器中:

{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会将资源键设置为您在其中指定的任何内容 .

2 回答

  • 1

    对你的问题的简短回答是 - 是的,它是WPF框架中的一个错误 . 这里报告了Bug .

    Update -

    Microsoft已经接受它是XAML编译器中的一个错误,他们并没有解决这个问题 . 来自微软的报价 -

    这是XAML编译器中的一个问题 - 它生成BAML来描述每个资源的密钥,通常基于x:Key(如果存在)和DataType(如果不存在) . 当x:Key本身是间接的(在您的情况下,使用x:Static),编译器选择DataType键 . 虽然选择x:基于静态的密钥可能更“正确”,但更改此选项会引入兼容性问题 . 此外,因为问题发生在编译时,您必须重新编译您的应用程序以查看修复(以生成不同的BAML流) . 应用程序的现有副本将包含旧的BAML流,并且在运行时的行为方式与现在相同 . 出于这个原因,我们决定不解决这个问题 .

    x:此处不忽略键,但在第一种情况下设置为 DataTemplateKey(WpfApplication1.TestDto) . 如果没有键值,则不能在“资源”部分下声明资源 .

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

    来自MSDN -

    此属性与Style类的TargetType属性非常相似 . 在不指定x:Key的情况下将此属性设置为数据类型时,DataTemplate将自动应用于该类型的数据对象 . 请注意,执行此操作时,将隐式设置x:Key . 因此,如果为此DataTemplate指定x:Key值,则覆盖隐式x:Key,并且不会自动应用DataTemplate .

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

    您可以通过将另一个DataTemplate添加到仅包含DataType设置的资源来验证,即

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

    它将编译正常,但会抛出运行时错误

    “项目已被添加 . 字典中的键:'DataTemplateKey(WpfApplication1.TestDto)'正在添加的键:'DataTemplateKey(WpfApplication1.TestDto)'”

  • 4

    我并不害羞,但会尝试将{get; set;}附加到 class 中的每个属性 . WPF中的一些工作人员(即Binding)在没有它们的情况下不起作用 . 可能在这里是同一个故事......

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

相关问题