c# wpf - Différence entre Style et ControlTemplate




xaml ui (5)

Pourriez-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 . Comme je suis débutant je pense que j'ai tort, donc ma question.


Answers

J'ai trouvé quelques différences intéressantes dans La différence entre les styles et les modèles (msdn)

Style: Vous ne pouvez définir que des propriétés préexistantes dans le style. Par exemple, vous ne pouvez pas définir une 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 la façon dont la liste déroulante apparaît dans une zone de liste déroulante ou modifier l'aspect du bouton qui déclenche la liste déroulante dans la zone de liste déroulante 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 un style pour un bouton, vous pouvez spécifier un déclencheur afin que lorsque les utilisateurs déplacent le pointeur de la souris sur le bouton, la couleur d'arrière-plan change. Ces changements de propriétés sont instantanés (ils ne peuvent pas être animés progressivement ).

Modèle: Vous pouvez spécifier le comportement de toutes les pièces nouvelles et existantes dans un modèle en utilisant des déclencheurs. Par exemple, vous pouvez spécifier un déclencheur afin que lorsque les utilisateurs déplacent le pointeur de la souris sur un bouton, la couleur de l'une des parties change. Ces changements de propriétés peuvent être instantanés ou animés progressivement pour produire une transition en douceur.


Non, en effet, vous avez tout à fait tort. Les styles définissent 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 groupe de propriétés afin de pouvoir les réutiliser pour standardiser vos contrôles. Les styles peuvent être définis explicitement sur les contrôles ou appliqués aussi tous d'un certain type.

Les modèles de contrôle peuvent être définis par un style ou définir explicitement sur un contrôle pour modifier la façon dont il apparaît. Tous les contrôles ont des modèles par défaut (et des styles d'ailleurs) qui sont incorporés dans les assemblys .net wpf. Il est très instructif 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 Expression blend installé, regardez dans son dossier "SystemThemes".

METTRE À JOUR:

Pour comprendre comment Styles et ControlTemplates peuvent "ajouter des contrôles". D'une manière ou d'une autre, ControlTemplate est le seul moyen de définir les contrôles d'un contrôle . Mais, 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>

Cela "ajoute" une case à cocher à la zone de groupe sans modifier le ControlTemplate , mais cela est dû au fait que le ControlTemplate par défaut pour GroupBox autorise tout en tant que l'en-tête . Ceci est fait en utilisant des contrôles spéciaux tels que ContentPresenter .

Cependant, le ControlTemplate par défaut pour un contrôle ne vous permet pas parfois 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 (Content, Header, ControlTemplate, IsEnabled, etc.) directement ou via un style n'a pas d'importance, les styles ne sont qu'une commodité.

J'espère que cela répond à votre question plus clairement.


OK, j'ai eu 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 le comprendre moi-même.

Un style est plus flexible qu'un ControlTemplate.

À partir de Windows Presentation Foundation Unleashed , Adam Nathan et le gang (écrivains) déclarent ceci:

  • "Outre la commodité de combiner un modèle [avec un style utilisant le Setter ControlTemplate du Style] avec des paramètres de propriété arbitraires, il y a des avantages importants à le faire [en réglant le setter ControlTemplate sur un style]:

    1. Cela vous donne l'effet des modèles par défaut. Par exemple, lorsqu'un style typé est appliqué aux éléments par défaut et que ce style contient un modèle de contrôle personnalisé, le modèle de contrôle est appliqué sans aucune marque explicite sur ces éléments.
    2. Il vous permet de fournir des valeurs de propriétés par défaut mais substituables qui contrôlent l'apparence du modèle. En d'autres termes, cela vous permet de respecter les propriétés du modèle, tout en fournissant vos propres valeurs par défaut. "

En d'autres termes, la création d'un style permet à l'utilisateur de l'éditeur de modèle de style de remplacer les valeurs définies, même s'il n'utilise pas de TemplateBinding ({TemplateBinding Width} par exemple). Si vous avez codé en dur la largeur dans votre style, l'utilisateur du style peut toujours la remplacer, mais si vous avez codé en dur cette propriété Width dans un modèle, l'utilisateur est coincé avec.

En outre, (et c'est un peu confus) lors de l'utilisation d'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 le TargetType. Si vous utilisez un style, vous pouvez remplacer la propriété par défaut de TargetType en utilisant un setter pour la propriété, puis en appliquant un référencement TemplateBinding à ce paramètre. Le livre l'explique mieux, page 338 (Mélanger des modèles avec des styles)


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 utilisant ce style verront leurs arrière-plans définis sur 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 utilisant ce modèle auront un fond vert qui ne peut pas être modifié.

Les valeurs définies dans un modèle ne peuvent être remplacées qu'en remplaçant le modèle entier. Les valeurs d'un style peuvent être remplacées en définissant explicitement la valeur lors de l'utilisation du contrôle. C'est pourquoi il vaut mieux 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 template utilise la valeur de la propriété Background du bouton auquel il est appliqué, donc il peut ê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 assigné. 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 le faire avec des modèles). Tous les boutons dans l'arborescence visuelle sous le style auront ce style appliqué.

La combinaison de modèles et de styles est très puissante: vous pouvez définir la propriété Modèle 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>

Il n'y a pas de différence entre les deux string, cependant, semble être l'option privilégiée lorsque l'on considère le code source d'autres développeurs.





c# .net wpf xaml