Pouvez-vous me dire quelles sont les principales différences entre Style et ControlTemplate? Quand ou pourquoi utiliser l’un ou l’autre?
À mes yeux, ils sont exactement les mêmes mêmes . En tant que débutant, je pense que je me trompe, d’où ma question.
Dans un style, vous définissez les propriétés d'un contrôle.
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Red"/>
</Style>
<Button Style="{StaticResource MyButtonStyle}"/>
Tous les boutons qui utilisent ce style auront leurs fonds définis en rouge.
Dans un modèle, vous définissez l'interface utilisateur (structure) du contrôle.
<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
<Grid>
<Rectangle Fill="Green"/>
<ContentPresenter/>
</Grid>
</ControlTemplate>
<Button Template="{StaticResource MyButtonTemplate}"/>
Tous les boutons qui utilisent ce modèle auront un fond vert qui ne peut pas être modifié.
Les valeurs définies dans un template ne peuvent être remplacées qu'en remplaçant le modèle entier. Les valeurs dans style peuvent être remplacées en définissant explicitement la valeur lors de l'utilisation du contrôle. C'est pourquoi il est préférable d'utiliser les propriétés du contrôle en utilisant TemplateBinding au lieu de coder des valeurs.
<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
<Grid>
<Rectangle Fill="{TemplateBinding Background}"/>
<ContentPresenter/>
</Grid>
</ControlTemplate>
Maintenant, le modèle utilise la valeur de la propriété Background du bouton auquel il est appliqué, il peut donc être personnalisé:
<Button Template="{StaticResource MyButtonTemplate}" Background="Yellow"/>
Une autre caractéristique utile est que les contrôles peuvent choisir un style par défaut sans qu’un style spécifique leur soit attribué. Vous ne pouvez pas faire cela avec un modèle.
Supprimez simplement l'attribut x: Key du style (encore une fois: vous ne pouvez pas faire cela avec des modèles). Ce style sera appliqué à tous les boutons de l'arborescence visuelle située sous le style.
Combiner des modèles et des styles est très puissant: vous pouvez définir la propriété Template dans le style:
<Style TargetType="Button">
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle Fill="{TemplateBinding Background"/>
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Non, en effet, vous avez tout à fait tort. Styles définit les propriétés sur les contrôles. ControlTemplate est une propriété partagée par la plupart des contrôles qui spécifient comment ils sont rendus.
Pour élaborer, vous pouvez utiliser un style pour regrouper les paramètres d'un ensemble de propriétés afin de pouvoir les réutiliser pour normaliser vos contrôles. Les styles peuvent être définis explicitement sur les contrôles ou appliqués à un certain type.
Les modèles de contrôle peuvent être définis par un style ou explicitement sur un contrôle pour changer son apparence. Tous les contrôles ont des modèles par défaut (et des styles d'ailleurs) incorporés dans les assemblys .net wpf. Il est très éclairant de les voir et de comprendre comment les développeurs de wpf ont implémenté les versions normales de tous les contrôles. Si vous avez installé Expression blend, recherchez-le dans le dossier "SystemThemes".
METTRE À JOUR:
Pour comprendre comment Styles et ControlTemplates peuvent "ajouter des contrôles". D'une manière ou d'une autre, le ControlTemplate est le seul moyen de définir les contrôles qui composent un contrôle . Toutefois, certains contrôles .net par défaut vous permettent d’utiliser des contrôles à la place du texte.
Par exemple:
<GroupBox>
<GroupBox.Header>
<CheckBox/>
</GroupBox.Header>
</GroupBox>
Ceci "ajoute" une case à cocher à la zone de groupe sans changer la ControlTemplate
, mais c'est parce que la valeur par défaut ControlTemplate
pour GroupBox
autorise tout ce qui est en-tête . Ceci est fait en utilisant des contrôles spéciaux tels que ContentPresenter
.
Cependant, parfois, le ControlTemplate par défaut d'un contrôle ne vous permet pas de modifier quelque chose que vous souhaitez modifier via les propriétés. Ensuite, vous devez changer le ControlTemplate.
Que vous définissiez les propriétés d'un contrôle (contenu, en-tête, ControlTemplate, IsEnabled, etc.) directement ou par le biais d'un style, les styles ne sont qu'une commodité.
J'espère que cela répond à votre question plus clairement.
Vous pouvez penser à un style comme un moyen pratique d’appliquer un ensemble de valeurs de propriété à plusieurs éléments. Vous pouvez modifier l'apparence par défaut en définissant directement des propriétés, telles que FontSize et FontFamily, sur chaque élément TextBlock. Toutefois, si vous souhaitez que vos éléments TextBlock partagent certaines propriétés, vous pouvez créer un style dans la section Ressources de votre fichier XAML.
D'autre part, un ControlTemplate spécifie la structure visuelle et le comportement visuel d'un contrôle. Vous pouvez personnaliser l'apparence d'un contrôle en lui attribuant un nouveau ControlTemplate. Lorsque vous créez un ControlTemplate, vous remplacez l'apparence d'un contrôle existant sans en modifier les fonctionnalités. Par exemple, vous pouvez arrondir les boutons de votre application à la place de la forme carrée par défaut, mais le bouton déclenche toujours l'événement Click.
J'ai trouvé des différences intéressantes dans La différence entre les styles et les modèles (msdn)
Style: Vous pouvez définir les propriétés uniquement préexistantes _ dans le style. Par exemple, vous ne pouvez pas définir de valeur par défaut pour une propriété appartenant à une nouvelle pièce que vous avez ajoutée au modèle.
Modèle: Lorsque vous modifiez un modèle, vous avez accès à plus de parties d'un contrôle} que lorsque vous modifiez un style. Par exemple, vous pouvez modifier l’apparence de la liste contextuelle dans une liste déroulante ou modifier l’apparence du bouton déclenchant la liste déroulante dans la zone combinée en modifiant le modèle d’éléments.
Style: Vous pouvez utiliser des styles pour spécifier le comportement par défaut d'un contrôle. Par exemple, dans le style d'un bouton, vous pouvez spécifier un déclencheur de sorte que lorsque l'utilisateur déplace le pointeur de la souris sur le bouton, la couleur d'arrière-plan change. Ces modifications de propriété sont instantanées (elles ne peuvent pas être animées progressivement).
Modèle: Vous pouvez spécifier le comportement de toutes les pièces nouvelles et existantes d'un modèle à l'aide de déclencheurs. Par exemple, vous pouvez spécifier un déclencheur de sorte que lorsque l'utilisateur déplace le pointeur de la souris sur un bouton, la couleur de l'une des pièces change. Ces modifications de propriété peuvent être instantanées ou animées progressivement _ afin de produire une transition en douceur.
D'accord, j'avais exactement la même question et les réponses que j'ai trouvées dans ce fil m'ont orienté dans la bonne direction, donc je partage, si seulement je peux mieux comprendre moi-même.
Un style est plus flexible qu'un ControlTemplate.
From Windows Presentation Foundation Unleashed , Adam Nathan et un gang (scénaristes) affirment ceci:
"Outre la possibilité de combiner un modèle [avec un style utilisant le setter ControlTemplate du style] avec des paramètres de propriété arbitraires, il existe des avantages importants à le faire [définir le setter ControlTemplate sur un style]:
En d'autres termes, la création d'un style permet à l'utilisateur du créateur de modèle du style de remplacer le jeu de valeurs, même s'il n'a pas utilisé TemplateBinding ({TemplateBinding Width}, par exemple). Si vous codez en dur la largeur dans votre style, l'utilisateur du style peut toujours la remplacer, mais si vous codez en dur cette propriété de largeur dans un modèle, l'utilisateur est coincé avec elle.
En outre, (et cela prête à confusion) lorsque vous utilisez un ContentTemplate avec un TemplateBinding, il incombe à l'utilisateur de définir cette propriété, sinon il utilisera la propriété par défaut pour TargetType. Si vous utilisez un style, vous pouvez remplacer la propriété par défaut du TargetType en utilisant un setter pour la propriété, puis en appliquant un TemplateBinding référençant à ce setter. Le livre explique mieux, page 338 (Mélanger des modèles avec des styles)