2013-10-18 9 views
9

我遇到了使用DataTemplate鍵的奇怪行爲:當通過x:Type指定DataType,並且通過x:Static reference指定了x:Key時,將忽略x:Key。我寫了示例應用程序來說明它。使用x指定時,將忽略DataTemplate鍵:靜態

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:鍵被忽略!

有人可以解釋發生了什麼? 文檔(http://msdn.microsoft.com/en-us/library/system.windows.datatemplate.datatype.aspx)明確指出,設置x:Key會將資源鍵設置爲您在其中指定的任何值。

+0

與bug非常相似。也許你應該嘗試寫connect.microsoft.com的反饋? –

回答

3

簡短的回答你的問題是 - 是的,它是在WPF框架的錯誤。 Bug報告here

更新 -

微軟已經接受了它在XAML編譯器的錯誤,他們不解決這個問題。從微軟報價 -

這是XAML編譯器的問題 - 它產生BAML描述 通常基於X每個資源的關鍵,如果關鍵是目前 和數據類型,如果它不是。當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你的資源,只有數據類型驗證即

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

它將編譯罰款,但會拋出運行時錯誤

「項目已添加鍵入詞典: ‘DataTemplateKey(WpfApplication1.TestDto)’鍵被添加: 「DataTemplateKey(WpfApplication1.TestDto )'「

+0

好的,謝謝你的回答,但你用不同的話跟我說了同樣的話。 –

+0

+1發佈到MS,我太懶惰 –

+0

是的簡短的回答你的問題將是一個錯誤。 :) –

1

我不舒服,這將有助於,但嘗試追加{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; } 
} 
+0

我試過了,難怪它沒有幫助。 x:靜態可以使用任何靜態屬性或字段。 –

+2

[offtop]尼斯尼克:) [/ offtop] –