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

Pav*_*syn 12 c# wpf xaml

我遇到了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}" />
Run Code Online (Sandbox Code Playgroud)

C#:

public class TestDto {}

public static class DataKeys
{
    public static string TestDtoKey = "TestKey";
    public static string TestDtoKey2 = "TestKey2";
    public static string TestDtoKey4 = "TestKey4";
}
Run Code Online (Sandbox Code Playgroud)

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

{DataTemplateKey(WpfApplication1.TestDto)}  object {System.Windows.DataTemplateKey}
"TestKey2"  object {string}
"TestKey3"  object {string}
"TestKey4"  object {string}
Run Code Online (Sandbox Code Playgroud)

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

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

Roh*_*ats 4

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

更新-

Microsoft 已承认这是 XAML 编译器中的错误,并且他们没有修复此问题。引用微软的话——

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

x:Key 在这里不会被忽略,但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,因此 key 被设置为DataTemplateKey(WpfApplication1.TestDto).

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

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

它会编译得很好,但会抛出运行时错误

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