Respostas:
Normalmente, um controle é renderizado por si só e não reflete dados subjacentes. Por exemplo, um Button
não seria vinculado a um objeto de negócios - ele existe apenas para que ele possa ser clicado. A ContentControl
ou ListBox
, no entanto, geralmente aparecem para que eles possam apresentar dados para o usuário.
A DataTemplate
, portanto, é usado para fornecer estrutura visual aos dados subjacentes, enquanto a ControlTemplate
não tem nada a ver com os dados subjacentes e simplesmente fornece layout visual para o próprio controle.
A ControlTemplate
geralmente conterá apenas TemplateBinding
expressões, vinculando de volta às propriedades no controle em si, enquanto a DataTemplate
conterá expressões de ligação padrão, vinculando-se às propriedades de seu DataContext
(o objeto de negócios / domínio ou o modelo de exibição).
Basicamente, a ControlTemplate
descreve como exibir um controle, enquanto DataTemplate
descreve como exibir dados.
Por exemplo:
A Label
é um controle e incluirá um ControlTemplate
que diz que Label
deve ser exibido usando um Border
conteúdo em torno de algum (um DataTemplate
ou outro controle).
Uma Customer
classe é Data e será exibida usando um DataTemplate
que poderia dizer exibir o Customer
tipo como um StackPanel
contendo dois, TextBlocks
mostrando o Nome e o outro exibindo o número de telefone. Pode ser útil observar que todas as classes são exibidas usando DataTemplates
, você geralmente usará o modelo padrão que é a TextBlock
com a Text
propriedade configurada para o resultado do ToString
método do Objeto .
Troels Larsen tem uma boa explicação no fórum do 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>
(Modelos roubados descaradamente de http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx e http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx respectivamente)
De qualquer forma, o ControlTemplate decide a aparência do botão, enquanto o ContentTemplate decide a aparência do conteúdo do botão. Assim, você pode vincular o conteúdo a uma de suas classes de dados e apresentá-lo como quiser.
ControlTemplate
: Representa o estilo de controle.
DataTemplate
: Representa o estilo dos dados (como você gostaria de mostrar seus dados).
Todos os controles estão usando o modelo de controle padrão que você pode substituir pela propriedade do modelo.
Por exemplo,
Button
modelo é um modelo de controle.
Button
modelo de conteúdo é um modelo de dados
<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
DEFINA a aparência visual, DataTemplate
SUBSTITUI a aparência visual de um item de dados.
Exemplo: quero mostrar um botão de retangular para circular = = Modelo de Controle.
E se você tiver objetos complexos para o controle, ele apenas chama e mostra ToString()
, com DataTemplate
você pode obter vários membros e exibir e alterar seus valores do objeto de dados.
Todas as respostas acima são ótimas, mas há uma diferença fundamental que foi perdida. Isso ajuda a tomar melhores decisões sobre quando usar o quê. É ItemTemplate
propriedade:
DataTemplate é usado para elementos que fornecem a propriedade ItemTemplate para você substituir o conteúdo de seus itens usando DataTemplate
s definidos anteriormente de acordo com os dados vinculados por meio de um seletor que você fornece.
Mas se o seu controle não fornecer esse luxo para você , você ainda poderá usar um ContentView
que possa exibir o conteúdo predefinido ControlTemplate
. Curiosamente, você pode alterar a ControlTemplate
propriedade do seu ContentView
em tempo de execução. Mais uma coisa a observar que, diferentemente dos controles com ItemTemplate
propriedade, você não pode ter um TemplateSelector
para esse controle (ContentView). No entanto, você ainda pode criar gatilhos para alterar o ControlTemplate
tempo de execução.