Partager via


Modèles de contrôle

Vous pouvez personnaliser la structure visuelle et le comportement visuel d’un contrôle en créant un modèle de contrôle dans l’infrastructure XAML. Les contrôles ont de nombreuses propriétés, telles que Background, Foreground et FontFamily, que vous pouvez définir pour spécifier différents aspects de l’apparence du contrôle. Toutefois, les modifications que vous pouvez apporter en définissant ces propriétés sont limitées. Vous pouvez spécifier des personnalisations supplémentaires en créant un modèle à l’aide de la classe ControlTemplate . Ici, nous vous montrons comment créer un ControlTemplate pour personnaliser l’apparence d’un contrôle CheckBox .

API importantes: classe ControlTemplate, propriété Control.Template

Exemple de modèle de contrôle personnalisé

Par défaut, un contrôle CheckBox place son contenu (la chaîne ou l'objet à côté de la case à cocher CheckBox) à droite de la case à cocher, et une coche indique qu’un utilisateur a sélectionné la case à cocher CheckBox. Ces caractéristiques représentent la structure visuelle et le comportement visuel du CheckBox .

Voici un CheckBox à l’aide de la ControlTemplate par défaut affichée dans les états , et .

modèle de case à cocher par défaut

Vous pouvez modifier ces caractéristiques en créant un ControlTemplate pour CheckBox. Par exemple, si vous souhaitez que le contenu de la case à cocher soit sous la zone de sélection et que vous souhaitez utiliser un X pour indiquer qu’un utilisateur a coché la case. Vous spécifiez ces caractéristiques dans le ControlTemplate du CheckBox.

Pour utiliser un modèle personnalisé avec un contrôle, affectez le ControlTemplate à la propriété modèle de du contrôle. Voici un CheckBox utilisant un ControlTemplate appelé CheckBoxTemplate1. Nous affichons le langage XAML (Extensible Application Markup Language) pour ControlTemplate dans la section suivante.

<CheckBox Content="CheckBox" Template="{StaticResource CheckBoxTemplate1}" IsThreeState="True" Margin="20"/>

Voici à quoi ressemble cette CheckBox dans les états Unchecked, Checkedet Indeterminate après l'application de notre modèle.

modèle de case à cocher personnalisé

Spécifier la structure visuelle d’un contrôle

Lorsque vous créez un ControlTemplate, vous combinez des objets FrameworkElement pour générer un seul contrôle. Un ControlTemplate ne doit avoir qu’un seul FrameworkElement comme élément racine. L’élément racine contient généralement d’autres objets FrameworkElement . La combinaison d’objets compose la structure visuelle du contrôle.

Ce code XAML crée un ControlTemplate pour un CheckBox qui spécifie que le contenu du contrôle se trouve sous la zone de sélection. L’élément racine est une Bordure. L'exemple spécifie un chemin d'accès pour créer un X qui indique qu'un utilisateur a sélectionné la case à cocher et une ellipse qui indique un état indéterminé. Notez que l'opacité est définie sur 0 pour le chemin et l'ellipse afin que, par défaut, aucun n'apparaissent.

Un TemplateBinding est une liaison spéciale qui lie la valeur d’une propriété dans un modèle de contrôle à la valeur d’une autre propriété exposée sur le contrôle modèle. TemplateBinding ne peut être utilisé que dans une définition ControlTemplate en XAML. Pour plus d’informations, consultez l’extension de balisage TemplateBinding .

Remarque

À compter de Windows 10, version 1809 (SDK 17763), vous pouvez utiliser des extensions de balisage x :Bind à des endroits où vous utilisez TemplateBinding. Pour plus d’informations, consultez l’extension de balisage TemplateBinding .

<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
    <Border BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
                       Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                       StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
                       UseLayoutRounding="False"/>
            <!-- Create an X to indicate that the CheckBox is selected. -->
            <Path x:Name="CheckGlyph"
                  Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
                  Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                  FlowDirection="LeftToRight"
                  Height="14" Width="16" Opacity="0" Stretch="Fill"/>
            <Ellipse x:Name="IndeterminateGlyph"
                     Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                     Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
            <ContentPresenter x:Name="ContentPresenter"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              Content="{TemplateBinding Content}"
                              Margin="{TemplateBinding Padding}" Grid.Row="1"
                              HorizontalAlignment="Center"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
    </Border>
</ControlTemplate>

Spécifier le comportement visuel d’un contrôle

Un comportement visuel spécifie l’apparence d’un contrôle lorsqu’il est dans un certain état. Le contrôle CheckBox a 3 états de sélection : Checked, Uncheckedet Indeterminate. La valeur de la propriété IsChecked détermine l’état du CheckBox, et son état détermine ce qui apparaît dans la case.

Ce tableau répertorie les valeurs possibles d’IsChecked, les états correspondants de CheckBox et l’apparence de CheckBox.

valeur IsChecked état du CheckBox apparence de la case à cocher
vrai Checked Contient un « X ».
faux Unchecked Vide.
zéro Indeterminate Contient un cercle.

Vous spécifiez l’apparence d’un contrôle lorsqu’il se trouve dans un état donné à l’aide d’objets VisualState . Un VisualState contient un Setter ou un Storyboard qui modifie l’aspect des éléments dans le ControlTemplate. Lorsque le contrôle entre dans l’état que spécifie la propriété VisualState.Name, les modifications de propriété dans le Setter ou le Storyboard sont appliquées. Lorsque le contrôle quitte l’état, les modifications sont supprimées. Vous ajoutez les objets VisualState aux objets VisualStateGroup. Vous ajoutez objets VisualStateGroup à la propriété jointe VisualStateManager.VisualStateGroup s, que vous définissez sur la racine FrameworkElement duControlTemplate .

Ce code XAML affiche les objets VisualState pour les états Checked, Unchecked, et Indeterminate. L’exemple définit la propriété jointe VisualStateManager.VisualStateGroups sur le, qui est l’élément racine du ControlTemplate . Le VisualState spécifie que le d’opacité du chemin d’accès nommé (que nous affichons dans l’exemple précédent) est 1. La VisualState spécifie que l' d’opacité du Ellipse nommé est 1. Unchecked n’a ni Setter ni Storyboard. Par conséquent, CheckBox revient à son apparence par défaut.

<ControlTemplate x:Key="CheckBoxTemplate1" TargetType="CheckBox">
    <Border BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}">

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CheckStates">
                <VisualState x:Name="Checked">
                    <VisualState.Setters>
                        <Setter Target="CheckGlyph.Opacity" Value="1"/>
                    </VisualState.Setters>
                    <!-- This Storyboard is equivalent to the Setter. -->
                    <!--<Storyboard>
                        <DoubleAnimation Duration="0" To="1"
                         Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>-->
                </VisualState>
                <VisualState x:Name="Unchecked"/>
                <VisualState x:Name="Indeterminate">
                    <VisualState.Setters>
                        <Setter Target="IndeterminateGlyph.Opacity" Value="1"/>
                    </VisualState.Setters>
                    <!-- This Storyboard is equivalent to the Setter. -->
                    <!--<Storyboard>
                        <DoubleAnimation Duration="0" To="1"
                         Storyboard.TargetName="IndeterminateGlyph" Storyboard.TargetProperty="Opacity"/>
                    </Storyboard>-->
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="25"/>
            </Grid.RowDefinitions>
            <Rectangle x:Name="NormalRectangle" Fill="Transparent" Height="20" Width="20"
                       Stroke="{ThemeResource SystemControlForegroundBaseMediumHighBrush}"
                       StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
                       UseLayoutRounding="False"/>
            <!-- Create an X to indicate that the CheckBox is selected. -->
            <Path x:Name="CheckGlyph"
                  Data="M103,240 L111,240 119,248 127,240 135,240 123,252 135,264 127,264 119,257 111,264 103,264 114,252 z"
                  Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                  FlowDirection="LeftToRight"
                  Height="14" Width="16" Opacity="0" Stretch="Fill"/>
            <Ellipse x:Name="IndeterminateGlyph"
                     Fill="{ThemeResource CheckBoxForegroundThemeBrush}"
                     Height="8" Width="8" Opacity="0" UseLayoutRounding="False" />
            <ContentPresenter x:Name="ContentPresenter"
                              ContentTemplate="{TemplateBinding ContentTemplate}"
                              Content="{TemplateBinding Content}"
                              Margin="{TemplateBinding Padding}" Grid.Row="1"
                              HorizontalAlignment="Center"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Grid>
    </Border>
</ControlTemplate>

Pour mieux comprendre comment fonctionnent VisualState objets, réfléchissez à ce qui se passe lorsque le CheckBox passe de l’état Unchecked à l’état Checked, puis à l’état Indeterminate, puis à l’état Unchecked. Voici les transitions.

Transition d’état Action exécutée Apparence de CheckBox lorsque la transition se termine
De Unchecked vers Checked. La valeur Setter de l' VisualState est appliquée. La d’opacité de est donc 1. Un X s’affiche.
De Checked vers Indeterminate. La valeur Setter de l' VisualState est appliquée. La d’opacité de est donc 1. La valeur Setter du VisualState est supprimée. Par conséquent, la d’opacité de est 0. Un cercle s’affiche.
De Indeterminate vers Unchecked. La valeur setter du VisualState est supprimée. Par conséquent, la d’opacité de est 0. Rien n’est affiché.

 Pour plus d’informations sur la création d’états visuels pour les contrôles, et notamment sur l’utilisation de la classe Storyboard et des types d’animations, consultez animations storyboarded pour les états visuels.

Utiliser facilement des outils pour travailler avec des thèmes

Un moyen rapide d’appliquer des thèmes à vos contrôles consiste à cliquer avec le bouton droit sur un contrôle sur le Plan du document Microsoft Visual Studio, puis à sélectionner Modifier le thème ou Modifier le style (selon le contrôle sur lequel vous cliquez avec le bouton droit). Vous pouvez ensuite appliquer un thème existant en sélectionnant Appliquer une ressource ou en définissant une nouvelle en sélectionnant Créer vide.

Contrôles et accessibilité

Lorsque vous créez un modèle pour un contrôle, en plus de modifier le comportement et l’apparence visuelle du contrôle, vous pouvez également changer la façon dont le contrôle se représente en infrastructures d’accessibilité. L’application Windows prend en charge l’infrastructure Microsoft UI Automation pour l’accessibilité. Tous les contrôles par défaut et leurs modèles prennent en charge les types et modèles de contrôle UI Automation courants appropriés à l’objectif et à la fonction du contrôle. Ces types et modèles de contrôle sont interprétés par des clients UI Automation tels que des technologies d’assistance, ce qui permet à un contrôle d’être accessible dans le cadre d’une interface utilisateur d’application plus large.

Pour séparer la logique de contrôle de base et également pour satisfaire certaines des exigences architecturales d’UI Automation, les classes de contrôle incluent leur prise en charge de l’accessibilité dans une classe distincte, un homologue Automation. Les homologues d’automatisation ont parfois des interactions avec les modèles de contrôle, car les homologues s’attendent à ce que certaines parties nommées existent dans les modèles, de sorte que les fonctionnalités telles que l’activation des technologies d’assistance pour appeler des actions de boutons sont possibles.

Lorsque vous créez un contrôle personnalisé entièrement nouveau, vous souhaiterez parfois également créer un pair d'automatisation pour l'accompagner. Pour plus d'informations, consultez partenaires d'automatisation personnalisés.

En savoir plus sur le modèle par défaut d’un contrôle

Les rubriques qui documentent les styles et les modèles des contrôles XAML vous montrent des extraits du même code XAML de départ que vous voyez si vous avez utilisé les techniques Modifier le thème ou Modifier le style expliquées précédemment. Chaque rubrique répertorie les noms des états visuels, les ressources de thème utilisées et le code XAML complet pour le style qui contient le modèle. Les rubriques peuvent être utiles si vous avez déjà commencé à modifier un modèle et que vous souhaitez voir à quoi ressemble le modèle d’origine, ou pour vérifier que votre nouveau modèle a tous les états visuels nommés requis.

Ressources de thème dans les modèles de contrôle

Pour certains des attributs des exemples XAML, vous avez peut-être remarqué des références de ressources qui utilisent l’extension de balisage {ThemeResource}. Il s’agit d’une technique qui permet à un modèle de contrôle unique d’utiliser des ressources qui peuvent être différentes valeurs selon le thème actuellement actif. Cela est particulièrement important pour les pinceaux et les couleurs, car l’objectif principal des thèmes est de permettre aux utilisateurs de choisir s’ils veulent un thème foncé, clair ou à contraste élevé appliqué au système dans l’ensemble. Les applications qui utilisent le système de ressources XAML peuvent utiliser un jeu de ressources approprié pour ce thème, de sorte que les choix de thème dans l’interface utilisateur d’une application reflètent le choix de thème à l’échelle du système de l’utilisateur.

Obtenir l’exemple de code