2012-03-03 32 views
6

考慮下面的XAML文件:爲什麼是X:在ResourceDictionary中所需的控件模板鍵

<Window x:Class="ExpressionVisualizer.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type sle:BinaryExpression}"/> 
     <ControlTemplate TargetType="{x:Type ContentControl}"/> 
    </Window.Resources> 
</Window> 

這是給下面的編譯錯誤:

All objects added to an IDictionary must have a Key attribute or some other type of key associated with them. Line 10 Position 10.

如果我添加一個x:key屬性的它編譯ControlTemplate。但是,我不應該那樣做。 ControlTemplate用DictionaryKeyProperty屬性裝飾,指定TargetType作爲key屬性。所以只要我爲ControlTemplate指定一個TargetType,我應該而不是必須指定一個顯式鍵(類似於我沒有在我定義的DataTemplate上指定一個鍵)。

我有第二個和切線相關的問題。如果我在XAML中以這種方式定義了一個ControlTemplate(或者指定了一個鍵),它是否會自動應用於ContentControl類型的所有控件,這些控件不指定另一個模板,還是必須將ControlTemplate嵌入到一個Style爲了發生?

回答

4

從MSDN ControlTemplate

If you have a standalone ControlTemplate in the resources section with the TargetType property set to a type, the ControlTemplate does not get applied to that type automatically. Instead, you need to specify an x:Key and apply the template explicitly.

Also note that the TargetType property is required on a ControlTemplate if the template
definition contains a ContentPresenter.

所以ControlTemplate不會自動應用,你必須始終指定x:Key。所以DictionaryKeyProperty不適用。

我做了一些研究:

雖然DictionaryKeyPropertyAttribute MSDN頁面狀態:

WPF Usage Notes

The following list references examples of WPF APIs where this attribute is applied:

ControlTemplate.TargetType 

DataTemplate.DataTemplateKey 

Style.TargetType 

Resources Overview頁面上,他們只提Styles, DataTemplates, and Implicit Keys其中有隱含的鑰匙。這也意味着,儘管有DictionaryKeyProperty,您仍然需要始終指定x:KeyControlTemplate

順便說一句,似乎有什麼問題DictionaryKeyPropertyAttirubte看到這connect issue

+0

這回答了我的問題的第二部分。我知道我需要指定一個x:Key,如果我想在文檔的其他地方引用該模板,但省略它不應該導致編譯錯誤。 – luksan 2012-03-03 20:52:11

+0

我已經更新了我的答案。它接縫'DictionaryKeyProperty'沒有做它應該是... – nemesv 2012-03-03 21:00:24

+0

DictionaryKeyProperty的問題似乎不會影響所有類型,因爲該屬性按照DataTemplate中指定的方式工作。連接問題是從2009年開始的。我想我只是把它寫成WPF中的另一件事情,它不起作用,從來沒有經過徹底的測試。每當我嘗試在WPF中開發某些東西時,我都會遇到這些類型的問題。這絕不會出現在Windows窗體上,一切正常。我真的認爲(或許是希望)他們將在4.0版本中讓WPF更具可預測性/可用性。 – luksan 2012-03-03 21:27:07

1

我不知道答案,你的第一個問題,但關於第二:

I have a second and tangentially related question. If I define a ControlTemplate in this way (either specifying a key or not) in the XAML, does it get automatically applied to all controls of type ContentControl that don't specify another template, or would I have to embed the ControlTemplate inside a Style for that to occur?

不,它不會自動應用。如果鍵與控件的DefaultStyleKey匹配,則會自動應用樣式;如果Content的類型與模板的DataType匹配,則數據模板將自動被ContentControl拾取。但控制模板並非如此;無論如何,控件模板通常被定義爲控件風格的一部分,它們很少直接應用於控件。

+0

+1,謝謝,我不知道DefaultStyleKey。 – luksan 2012-03-03 20:47:29

0
<Window x:Class="ExpressionVisualizer.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="DT" DataType="{x:Type sle:BinaryExpression}"/> 
    <ControlTemplate x:Key="CT" TargetType="{x:Type ContentControl}"/> 
</Window.Resources> 

主要用於對控制應用模板等爲按鈕,文本框,文本塊等,如果你不使用則模板化是行不通的。

0

如果你想控制模板將應用到所有指定的類型,你可以定義一個樣式,並設置模板屬性和風格的TargetType到你指定的控制:

<Window x:Class="ExpressionVisualizer.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:sle="clr-namespace:System.Linq.Expressions;assembly=System.Core" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="DT" DataType="{x:Type sle:BinaryExpression}"/> 
    <ControlTemplate x:Key="CT" TargetType="{x:Type ContentControl}"/> 
    <Style TargetType="ContentControl"> 
     <Setter Property="Template" Value="{StaticResource CT}"></Setter> 
    </Style> 
</Window.Resources> 

我用這個測試按鈕目標類型,但我認爲它應該以這種方式工作。