回答:
通常、コントロールはそれ自体のためにレンダリングされ、基になるデータを反映しません。たとえば、a Button
はビジネスオブジェクトにバインドされません-純粋にそこにあるので、クリックできます。A ContentControl
またはがListBox
、しかし、一般的に、彼らは、ユーザーのデータを提示することができるように表示されます。
AはDataTemplate
、つつ、データの基礎をなすための視覚的な構造を提供するために使用されるControlTemplate
基礎となるデータとは何の関係もないし、単に制御自体の視覚的なレイアウトを提供します。
ControlTemplate
通常、AにはTemplateBinding
式のみが含まれ、コントロール自体のプロパティにDataTemplate
バインドされます。一方、A には標準のBinding式が含まれ、そのプロパティDataContext
(ビジネス/ドメインオブジェクトまたはビューモデル)にバインドされます。
非常に基本的には、a ControlTemplate
はコントロールを表示するDataTemplate
方法を説明し、a はデータを表示する方法を説明します。
例えば:
A Label
はコントロールであり、一部のコンテンツ(または別のコントロール)を使用してを表示ControlTemplate
するLabel
必要があることを示すが含まれます。Border
DataTemplate
Customer
クラスがデータであり、使用して表示するDataTemplate
表示すると言うことができるどのCustomer
ようなタイプをStackPanel
含む二つのTextBlocks
電話番号を表示する名前を示す一方及び他方。それは、すべてのクラスが使用して表示されていることに注意すると便利かもしれないDataTemplates
、あなただけの通常デフォルトテンプレート使用するTextBlock
とText
オブジェクトの結果にプロパティセットToString
方法を。
Troels LarsenがMSDNフォーラムで良い説明をしています
<Window x:Class="WpfApplication7.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <DataTemplate x:Key="ButtonContentTemplate"> <StackPanel Orientation="Horizontal"> <Grid Height="8" Width="8"> <Path HorizontalAlignment="Stretch" Margin="0,0,1.8,1.8" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" Data="M0.5,5.7 L0.5,0.5 L5.7,0.5"/> <Path HorizontalAlignment="Stretch" Margin="2,3,0,0" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" Data="M3.2,7.5 L7.5,7.5 L7.5,3.5"/> <Path HorizontalAlignment="Stretch" Margin="1.2,1.4,0.7,0.7" VerticalAlignment="Stretch" Fill="#FFFFFFFF" Stretch="Fill" Stroke="#FF000000" Data="M2.5,2.5 L7.5,7.5"/> <Path HorizontalAlignment="Stretch" Margin="1.7,2.0,1,1" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FF000000" Data="M3,7.5 L7.5,7.5 L7.5,3.5"/> <Path HorizontalAlignment="Stretch" Margin="1,1,1,1" VerticalAlignment="Stretch" Stretch="Fill" Stroke="#FFFFFFFF" Data="M1.5,6.5 L1.5,1 L6.5,1.5"/> </Grid> <ContentPresenter Content="{Binding}"/> </StackPanel> </DataTemplate> <ControlTemplate TargetType="Button" x:Key="ButtonControlTemplate"> <Grid> <Ellipse Fill="{TemplateBinding Background}"/> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Window.Resources> <StackPanel> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="1"/> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="2"/> <Button Template="{StaticResource ButtonControlTemplate}" ContentTemplate="{StaticResource ButtonContentTemplate}" Content="3"/> </StackPanel> </Window>
(http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx および http://msdn.microsoft.com/en-us/library/system.windowsから露骨に盗まれたテンプレート .controls.contentcontrol.contenttemplate%28VS.95%29.aspx それぞれ)
とにかく、ControlTemplateはボタン自体の外観を決定し、ContentTemplateはボタンのコンテンツの外観を決定します。したがって、コンテンツをデータクラスの1つにバインドし、必要に応じてコンテンツを表示させることができます。
ControlTemplate
:コントロールスタイルを表します。
DataTemplate
:データスタイルを表します(データをどのように表示しますか)。
すべてのコントロールは、テンプレートプロパティを介してオーバーライドできるデフォルトのコントロールテンプレートを使用しています。
たとえば、
Button
テンプレートはコントロールテンプレートです。
Button
コンテンツテンプレートはデータテンプレートです
<Button VerticalAlignment="Top" >
<Button.Template>
<ControlTemplate >
<Grid>
<Rectangle Fill="Blue" RadiusX="20" RadiusY="20"/>
<Ellipse Fill="Red" />
<ContentPresenter Content="{Binding}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="50">
<TextBlock Text="Name" Margin="5"/>
<TextBox Text="{Binding UserName, Mode=TwoWay}" Margin="5" Width="100"/>
<Button Content="Show Name" Click="OnClickShowName" />
</StackPanel>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
public String UserName
{
get { return userName; }
set
{
userName = value;
this.NotifyPropertyChanged("UserName");
}
}
上記の答えはすべて素晴らしいですが、見逃された重要な違いがあります。これは、いつ何を使用するかについてより良い決定を下すのに役立ちます。それはItemTemplate
財産です:
DataTemplateは、ItemTemplateプロパティを提供する要素に使用され、提供DataTemplate
するセレクターを介してバインドされたデータに従って以前に定義したsを使用してアイテムのコンテンツを置き換えることができます。
ただし、コントロールがこの贅沢さを提供しない場合でもContentView
、事前定義されControlTemplate
たからコンテンツを表示できるを使用できます。興味深いことに、実行時にのControlTemplate
プロパティを変更できContentView
ます。ItemTemplate
プロパティ付きのコントロールとは異なりTemplateSelector
、この(ContentView)コントロールは使用できないことに注意してください。ただし、トリガーを作成ControlTemplate
して実行時にを変更することはできます。