我遇到了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会将资源键设置为您在其中指定的任何内容.
对您问题的简短回答是 - 是的,这是 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)'”
| 归档时间: |
|
| 查看次数: |
1242 次 |
| 最近记录: |