【问题标题】:DataTemplate key is ignored when specified with x:Static使用 x:Static 指定时忽略 DataTemplate 键
【发布时间】:2013-10-30 14:32:41
【问题描述】:

我遇到了使用 DataTemplate 键的奇怪行为:当通过 x:Type 指定 DataType 并且通过 x:Static 引用指定 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 会将资源密钥设置为您在其中指定的任何内容。

【问题讨论】:

  • 非常类似于这个bug。也许您应该尝试为 connect.microsoft.com 写反馈?

标签: c# wpf xaml


【解决方案1】:

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

更新 -

Microsoft 已接受这是 XAML 编译器中的一个错误,并且他们不会修复此问题。来自微软的引述 -

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

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

如您所见,此处的密钥自动设置为DataTemplateKey(WpfApplication1.TestDto)

来自MSDN-

这个属性与 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)

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

&lt;DataTemplate DataType="{x:Type wpfApplication1:TestDto}"/&gt;.

可以正常编译,但会抛出运行时错误

"项目已添加。在字典中键入: 'DataTemplateKey(WpfApplication1.TestDto)' 键被添加: 'DataTemplateKey(WpfApplication1.TestDto)'"

【讨论】:

  • 嗯,谢谢你的回答,但你只是用不同的词和我说了同样的话。
  • 是的,对您的问题的简短回答将是一个错误。 :)
  • 随微软响应更新。他们已经接受了这个缺陷,并且由于兼容性问题不会修复这个问题。
【解决方案2】:

我不确定这会有所帮助,但请尝试将 {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; }
}

【讨论】:

  • 我试过了,难怪没有帮助。 x:Static 适用于任何静态属性或字段。
  • [offtop] 不错的 nick :) [/offtop]
猜你喜欢
  • 2018-08-22
  • 2012-02-01
  • 2012-04-15
  • 1970-01-01
  • 2014-10-24
  • 2014-10-04
  • 2021-10-15
  • 2012-08-11
  • 1970-01-01
相关资源
最近更新 更多