c# - 使用 x :Static 指定时忽略 DataTemplate 键

标签 c# wpf xaml

我遇到了 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 会将资源 key 设置为您在其中指定的任何内容。

最佳答案

Short answer to your question is - YES it's a bug in WPF framework. Bug reported here.

更新 -

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

This is an issue in the XAML compiler - it produces BAML to describe the key for each resource, normally based on the x:Key if it's present and on the DataType if it's not. When x:Key is itself indirect (in your case, using x:Static), the compiler chooses the DataType key. While choosing the x:Static-based key is probably more "correct", changing this would introduce compatibility issues. Also, because the issue occurs at compile-time, you'd have to recompile your app to see the fix (to generate a different BAML stream). Existing copies of your app would contain the old BAML stream, and would behave the same way at runtime as they do now. For this reason we are deciding to won't fix this issue.

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

如您所见, key 自动设置为 DataTemplateKey(WpfApplication1.TestDto)在这里。

来自 MSDN -

This property that is very similar to the TargetType property of the Style class. When you set this property to the data type without specifying an x:Key, the DataTemplate gets applied automatically to data objects of that type. Note that when you do that the x:Key is set implicitly. Therefore, if you assign this DataTemplate an x:Key value, you are overriding the implicit x:Key and the DataTemplate would not be applied automatically.

以某种方式,以防你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}"/> .

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

"Item has already been added. Key in dictionary: 'DataTemplateKey(WpfApplication1.TestDto)' Key being added: 'DataTemplateKey(WpfApplication1.TestDto)'"

关于c# - 使用 x :Static 指定时忽略 DataTemplate 键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19452800/

相关文章:

c# - 改进噪声的版本不断返回 0

WPF 样式 DataGridHyperlinkColumn

wpf - 如何为多个鼠标悬停事件创建单一样式?

c# - WPF 在代码中添加的行未显示 - 显示 XAML

wpf - 覆盖切换按钮样式

javascript - 单击按钮时发出警报

c# - 使用 ToArray() 将列表转换为数组

C# 修饰符 'abstract' 对此项无效

wpf - 为什么在 Windows 中缩放 WPF 应用程序时会看到像素?

c# - UI 中等待任务的问题