Ответы:
Обычно элемент управления создается сам по себе и не отражает базовые данные. Например, Button
бизнес-объект не будет привязан - он существует только для того, чтобы на него можно было нажать. А ContentControl
или ListBox
, как правило, появляются так, что они могут представлять данные для пользователя.
A DataTemplate
, следовательно, используется для предоставления визуальной структуры для базовых данных, в то время как a не ControlTemplate
имеет ничего общего с базовыми данными и просто предоставляет визуальную компоновку для самого элемента управления.
A ControlTemplate
обычно будет содержать только выражения, привязывающие к свойствам самого элемента TemplateBinding
управления, тогда как a DataTemplate
будет содержать стандартные выражения Binding, привязывающие к свойствам его DataContext
(объект бизнес / домен или модель представления).
Очень в основном ControlTemplate
описывает, как отображать элемент управления, а DataTemplate
описывает, как отображать данные.
Например:
A Label
является элементом управления и будет включать в себя элемент, ControlTemplate
который говорит, что Label
должен отображаться с использованием Border
некоторого содержимого (a 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
вы определили ранее в соответствии с привязанными данными через предоставленный вами селектор.
Но если ваш контроль не предоставляет такую роскошь для вас, вы все равно можете использовать тот, ContentView
который может отображать его содержимое из предопределенных ControlTemplate
. Интересно, что вы можете изменить ControlTemplate
свойство вашего ContentView
во время выполнения. Еще одна вещь, на которую следует обратить внимание: в отличие от элементов управления со ItemTemplate
свойством, у вас не может быть элемента управления TemplateSelector
для этого (ContentView). Тем не менее, вы все еще можете создавать триггеры для изменения ControlTemplate
во время выполнения.