Відповіді:
Зазвичай контроль надається заради себе, а не відображає основні дані. Наприклад, Button
не буде прив’язаний до бізнес-об’єкта - він там суто, щоб на нього можна було натиснути. А ContentControl
або ListBox
, як правило, з'являються таким чином, щоб вони могли представити дані для користувача.
Таким DataTemplate
чином, A використовується для забезпечення візуальної структури базових даних, тоді як a ControlTemplate
не має нічого спільного з базовими даними і просто забезпечує візуальну компоновку для самого управління.
A ControlTemplate
, як правило, міститиме лише TemplateBinding
вирази, прив'язуючи до властивостей самого DataTemplate
елемента управління, тоді як a буде містити стандартні вирази прив'язки, прив'язки до властивостей його DataContext
(об'єкт бізнес / домен або модель перегляду).
В основному це ControlTemplate
опис, як відобразити елемент керування, а DataTemplate
опис відображення даних.
Наприклад:
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 вирішує, як виглядає вміст кнопки. Таким чином, ви можете прив’язати вміст до одного з ваших класів даних і подати його, як би ви цього хотіли.
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");
}
}
ControlTemplate
ВИЗНАЧАЄ візуальний зовнішній вигляд, DataTemplate
ЗАМІНУЄ візуальний вигляд елемента даних.
Приклад: Я хочу показати кнопку від прямокутної до форми кола => Шаблон управління.
І якщо у вас є складні об'єкти для управління, вони просто дзвонять і показують ToString()
, DataTemplate
ви можете отримувати різні члени та відображати та змінювати їх значення об'єкта даних.
Усі вищезазначені відповіді чудові, але є ключова різниця, яка була пропущена. Це допомагає приймати кращі рішення про те, коли використовувати. Це ItemTemplate
майно:
DataTemplate використовується для елементів, які надають вам властивість ItemTemplate для заміни вмісту його елементів, використовуючи DataTemplate
s, визначені раніше відповідно до зв'язаних даних через селектор, який ви надаєте.
Але якщо ваш контроль не надає вам такої розкоші, ви все одно можете скористатися ContentView
вмістом, який може відображати його вміст із попередньо визначених ControlTemplate
. Цікаво, що ви можете змінити ControlTemplate
властивість своїх ContentView
під час виконання. Ще одне, що слід зазначити, що на відміну від елементів керування з ItemTemplate
властивістю, ви не можете мати TemplateSelector
для цього (ContentView) контроль. Однак ви все одно можете створити тригери, щоб змінити час ControlTemplate
виконання.