Odpowiedzi:
Zwykle formant jest renderowany dla samego siebie i nie odzwierciedla podstawowych danych. Na przykład obiekt Button
nie byłby związany z obiektem biznesowym - jest tam wyłącznie, aby można go było kliknąć. A ContentControl
lub ListBox
, na ogół, pojawiają się, aby móc przedstawić dane dla użytkownika.
A DataTemplate
zatem służy do zapewnienia wizualnej struktury bazowych danych, podczas gdy ControlTemplate
nie ma nic wspólnego z podstawowymi danymi i po prostu zapewnia wizualny układ samej kontrolki.
A na ControlTemplate
ogół będzie zawierać tylko TemplateBinding
wyrażenia, wiążące się z właściwościami samego formantu, podczas gdy a DataTemplate
będzie zawierało standardowe wyrażenia Binding, wiążące się z właściwościami jego DataContext
(obiektu biznesowego / domeny lub modelu widoku).
Zasadniczo ControlTemplate
opisuje sposób wyświetlania Kontroli, a DataTemplate
opisuje sposób wyświetlania Danych.
Na przykład:
A Label
jest formantem, który będzie zawierał komunikat, ControlTemplate
który Label
powinien być wyświetlany przy użyciu Border
jakiejś Treści (a DataTemplate
lub innej Kontroli).
Customer
Klasa danych i będą wyświetlane za pomocą DataTemplate
których można powiedzieć, aby wyświetlić Customer
typ jako StackPanel
zawierający dwie TextBlocks
jeden pokazujący nazwę i inne wyświetlanie numeru telefonu. Może to być pomocne, aby pamiętać, że wszystkie klasy są wyświetlane przy użyciu DataTemplates
, będzie tylko zazwyczaj użyć domyślnego szablonu, który jest TextBlock
z Text
właściwości zestawu do wyniku obiektu ToString
metody.
Troels Larsen ma dobre wyjaśnienie na forum 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>
(Szablony rażąco skradzione z http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx i http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% odpowiednio 29.aspx )
W każdym razie ControlTemplate decyduje o wyglądzie samego przycisku, a ContentTemplate decyduje o wyglądzie zawartości przycisku. Możesz więc powiązać zawartość z jedną z klas danych i sprawić, by prezentowała się tak, jak chcesz.
ControlTemplate
: Reprezentuje styl kontroli.
DataTemplate
: Reprezentuje styl danych (Jak chcesz pokazać swoje dane).
Wszystkie formanty używają domyślnego szablonu kontroli, który można zastąpić za pomocą właściwości szablonu.
Na przykład
Button
szablon jest szablonem sterującym.
Button
szablon treści to szablon danych
<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");
}
}
ControlTemplate
OKREŚLA wygląd wizualny, WYMIENIA wygląd DataTemplate
zewnętrzny elementu danych.
Przykład: Chcę pokazać przycisk z formularza prostokątnego do koła => Szablon kontrolny.
A jeśli masz złożone obiekty do kontroli, to po prostu wywołuje i pokazuje ToString()
, dzięki DataTemplate
czemu możesz uzyskać różnych członków oraz wyświetlać i zmieniać ich wartości obiektu danych.
Wszystkie powyższe odpowiedzi są świetne, ale brakuje istotnej różnicy. Pomaga to podejmować lepsze decyzje o tym, kiedy z czego korzystać. Jest ItemTemplate
własnością:
DataTemplate jest używany w przypadku elementów, które zapewniają właściwość ItemTemplate w celu zastąpienia zawartości jego elementów za pomocą DataTemplate
s zdefiniowanych wcześniej zgodnie z powiązanymi danymi za pomocą podanego selektora.
Ale jeśli twoja kontrola nie zapewni ci tego luksusu , nadal możesz użyć takiego, ContentView
który może wyświetlać jego zawartość z góry określonych ControlTemplate
. Co ciekawe, możesz zmienić ControlTemplate
właściwość swojego ContentView
w czasie wykonywania. Trzeba jeszcze zauważyć, że w przeciwieństwie do kontrolek z ItemTemplate
właściwością, nie można mieć TemplateSelector
kontrolki (ContentView). Nadal można jednak tworzyć wyzwalacze, które zmieniają ControlTemplate
środowisko wykonawcze.