Quelle est la différence entre un ControlTemplate
et un DataTemplate
dans WPF?
Généralement, un contrôle est rendu pour son propre compte et ne reflète pas les données sous-jacentes. Par exemple, un Button
ne serait pas lié à un objet métier - il existe uniquement pour que vous puissiez cliquer dessus. Un ContentControl
ou ListBox
apparaît toutefois généralement pour pouvoir présenter des données à l'utilisateur.
Par conséquent, un DataTemplate
est utilisé pour fournir une structure visuelle aux données sous-jacentes, tandis qu'un ControlTemplate
n'a rien à voir avec les données sous-jacentes et fournit simplement une présentation visuelle du contrôle lui-même.
Un ControlTemplate
ne contiendra généralement que des expressions TemplateBinding
, renvoyant aux propriétés du contrôle lui-même, alors qu'un DataTemplate
contiendra des expressions de liaison standard, liant les propriétés de son DataContext
(objet métier/domaine ou modèle de vue).
En gros, un ControlTemplate
décrit comment afficher un contrôle alors qu'un DataTemplate
décrit comment afficher des données.
Par exemple:
Un Label
est un contrôle et inclura un ControlTemplate
qui indique que le Label
doit être affiché à l'aide d'un Border
autour d'un contenu (un DataTemplate
ou un autre contrôle).
Une classe Customer
est Data et sera affichée à l'aide d'un DataTemplate
qui pourrait indiquer d'afficher le type Customer
comme un StackPanel
contenant deux TextBlocks
l'un affichant le nom et l'autre 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 propriété Text
définie sur le résultat de la méthode ToString
de l'objet.
Troels Larsen a une bonne explication sur 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 manifestement volés de http://msdn.Microsoft.com/en-us/library/system.windows.controls.controltemplate.aspx et http://msdn.Microsoft. com/fr-fr/library/system.windows.controls.contentcontrol.contenttemplate% 28VS.95% 29.aspx ) respectivement
Quoi qu'il en soit, le ControlTemplate décide de l'apparence du bouton lui-même, tandis que le ContentTemplate détermine l'apparence du contenu du bouton. Ainsi, vous pouvez lier le contenu à l'une de vos classes de données et le présenter comme vous le souhaitez.
ControlTemplate
: représente le style de contrôle.
DataTemplate
: représente le style de données (comment voudriez-vous afficher vos données).
Tous les contrôles utilisent un modèle de contrôle par défaut que vous pouvez remplacer par la propriété du modèle.
Par exempleButton
template est un template de contrôle. Button
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
- Changer l'apparence de l'élément. Par exemple, Button
peut contenir une image et du texte
DataTemplate
- Représentant les données sous-jacentes à l'aide des éléments.
ControlTemplate
Définit l'apparence visuelle, DataTemplate
REMPLACE l'apparence visuelle d'un élément de données.
Exemple: je souhaite afficher un bouton de forme rectangulaire à forme circulaire => Modèle de contrôle.
Et si vous avez des objets complexes dans le contrôle, il appelle simplement et affiche ToString()
, avec DataTemplate
, vous pouvez obtenir divers membres et afficher et modifier leurs valeurs de l'objet de données.