Réponses:
En règle générale, un contrôle est rendu pour lui-même et ne reflète pas les données sous-jacentes. Par exemple, un Button
ne serait pas lié à un objet métier - il est là uniquement pour qu'il puisse être cliqué. A ContentControl
ou ListBox
, cependant, apparaissent généralement afin de pouvoir présenter des données pour l'utilisateur.
A DataTemplate
, par conséquent, est utilisé pour fournir une structure visuelle pour les données sous-jacentes, tandis que ControlTemplate
a n'a rien à voir avec les données sous-jacentes et fournit simplement une disposition visuelle pour le contrôle lui-même.
Un ControlTemplate
ne contiendra généralement que des TemplateBinding
expressions, se liant aux propriétés du contrôle lui-même, tandis qu'un DataTemplate
contiendra des expressions de liaison standard, se liant aux propriétés de son DataContext
(objet métier / domaine ou modèle de vue).
Fondamentalement, un ControlTemplate
décrit comment afficher un contrôle tandis qu'un DataTemplate
décrit comment afficher des données.
Par exemple:
A Label
est un contrôle et comprendra un ControlTemplate
qui indique que le Label
doit être affiché à l'aide d'un Border
autour de certains contenus (un DataTemplate
ou un autre contrôle).
Une Customer
classe est Data et sera affichée en utilisant un DataTemplate
qui pourrait dire d'afficher le Customer
type comme StackPanel
contenant deux l' TextBlocks
un indiquant le nom et l'autre affichant le numéro de téléphone. Il peut être utile de noter que toutes les classes sont affichées en utilisant DataTemplates
, vous utiliserez généralement le modèle par défaut qui est un TextBlock
avec la Text
propriété définie sur le résultat de la ToString
méthode de l'objet .
Troels Larsen a une bonne explication sur le 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>
(Modèles volés de manière flagrante sur http://msdn.microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx et http://msdn.microsoft.com/en-us/library/system.windows .controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx respectivement)
Quoi qu'il en soit, le ControlTemplate décide à quoi ressemble le bouton lui-même, tandis que le ContentTemplate décide à quoi ressemble le contenu du bouton. Vous pouvez donc lier le contenu à l'une de vos classes de données et le présenter tel que vous le souhaitez.
ControlTemplate
: Représente le style de contrôle.
DataTemplate
: Représente le style de données (comment souhaitez-vous afficher vos données).
Tous les contrôles utilisent un modèle de contrôle par défaut que vous pouvez remplacer via la propriété du modèle.
Par exemple, le
Button
modèle est un modèle de contrôle.
Button
le modèle de contenu est un modèle de données
<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
DÉFINIT l'apparence visuelle, DataTemplate
REMPLACE l'apparence visuelle d'un élément de données.
Exemple: je veux montrer un bouton de forme rectangulaire à circulaire => Modèle de contrôle.
Et si vous avez des objets complexes à contrôler, il appelle et affiche simplement ToString()
, avec DataTemplate
vous pouvez obtenir différents membres et afficher et modifier leurs valeurs de l'objet de données.
Toutes les réponses ci-dessus sont excellentes mais il y a une différence clé qui a été manquée. Cela aide à prendre de meilleures décisions sur le moment d'utiliser quoi. C'est la ItemTemplate
propriété:
DataTemplate est utilisé pour les éléments qui fournissent la propriété ItemTemplate pour vous permettre de remplacer le contenu de ses éléments à l'aide de DataTemplate
s que vous définissez précédemment en fonction des données liées via un sélecteur que vous fournissez.
Mais si votre contrôle ne vous offre pas ce luxe, vous pouvez toujours utiliser un ContentView
qui peut afficher son contenu à partir de prédéfinis ControlTemplate
. Fait intéressant, vous pouvez modifier la ControlTemplate
propriété de votre ContentView
au moment de l'exécution. Une dernière chose à noter que contrairement aux contrôles avec ItemTemplate
propriété, vous ne pouvez pas avoir de TemplateSelector
contrôle pour ce contenu (ContentView). Cependant, vous pouvez toujours créer des déclencheurs pour modifier le ControlTemplate
au moment de l'exécution.