Partager via


Styles XAML

Vous pouvez personnaliser l’apparence de vos applications de plusieurs façons à l’aide de l’infrastructure XAML. Les styles vous permettent de définir des propriétés de contrôle et de réutiliser ces paramètres pour une apparence cohérente entre plusieurs contrôles.

WinUI et styles

À compter de WinUI 2.2, nous avons utilisé WinUI pour fournir de nouvelles mises à jour de style visuel sur nos composants d’interface utilisateur. Si vous remarquez que votre interface utilisateur n’est pas mise à jour vers les derniers styles, veillez à effectuer une mise à jour vers le dernier package NuGet WinUI.

À compter de WinUI 2.6, nous fournissons de nouveaux styles pour la plupart des contrôles et un nouveau système de gestion de versions qui vous permet de revenir aux styles de contrôle précédents si nécessaire. Nous vous encourageons à utiliser les nouveaux styles, car ils correspondent mieux à la direction de conception de Windows. Toutefois, si votre scénario ne peut pas prendre en charge les nouveaux styles, les versions précédentes sont toujours disponibles.

Vous pouvez modifier la version de style en définissant la propriété ControlsResourcesVersion sur l'élément XamlControlsResources que vous incluez dans votre Application.Resources lorsque vous utilisez la version 2 de WinUI. ControlsResourcesVersion a comme valeur par défaut l'énumération Version2.

Définir cette valeur sur Version1 entraîne le chargement par XamlControlsResources des versions de style précédentes au lieu des nouveaux styles utilisés par la dernière version de WinUI. La modification de cette propriété au moment de l’exécution n’est pas prise en charge et la fonctionnalité de rechargement à chaud de VisualStudio ne fonctionnera pas ; Toutefois, après avoir reconstruit votre application, vous verrez que les styles de contrôle changent.

<Application.Resources>
    <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" 
                           ControlsResourcesVersion="Version1"/>
</Application.Resources>

Principes de base du style

Utilisez des styles pour extraire les paramètres de propriété visuelle dans des ressources réutilisables. Voici un exemple montrant 3 boutons avec un style qui définit les propriétés BorderBrush , BorderThickness et Foreground . En appliquant un style, vous pouvez rendre les contrôles identiques sans avoir à définir ces propriétés sur chaque contrôle séparément.

Capture d’écran de trois boutons de style disposés côte à côte.

Vous pouvez définir un style inline dans le code XAML pour un contrôle ou en tant que ressource réutilisable. Définissez les ressources dans le fichier XAML d’une page individuelle, dans le fichier App.xaml ou dans un fichier XAML de dictionnaire de ressources distinct. Un fichier XAML de dictionnaire de ressources peut être partagé entre les applications, et plusieurs dictionnaires de ressources peuvent être fusionnés dans une seule application. L’emplacement où la ressource est définie détermine l’étendue dans laquelle elle peut être utilisée. Les ressources au niveau de la page sont disponibles uniquement dans la page où elles sont définies. Si les ressources avec la même clé sont définies dans App.xaml et dans une page, la ressource de la page remplace la ressource dans App.xaml. Si une ressource est définie dans un fichier de dictionnaire de ressources distinct, son étendue est déterminée par l’emplacement où le dictionnaire de ressources est référencé.

Dans la définition style , vous avez besoin d’un attribut TargetType et d’une collection d’un ou plusieurs éléments setter . L’attribut TargetType est une chaîne qui spécifie un type FrameworkElement auquel appliquer le style. La valeur TargetType doit spécifier un type dérivé de FrameworkElement défini par Windows Runtime ou un type personnalisé disponible dans un assembly référencé. Si vous essayez d’appliquer un style à un contrôle et que le type du contrôle ne correspond pas à l’attribut TargetType du style que vous essayez d’appliquer, une exception se produit.

Chaque élément Setter de nécessite un Property et une Value. Ces paramètres de propriété indiquent la propriété de contrôle à laquelle le paramètre s’applique et la valeur à définir pour cette propriété. Vous pouvez définir l'Setter.Value avec la syntaxe d’attribut ou d’élément de propriété. Le code XAML montre ici le style appliqué aux boutons affichés précédemment. Dans ce code XAML, les deux premiers éléments Setter utilisent la syntaxe d’attribut, mais le dernier Setter, pour la propriété BorderBrush , utilise la syntaxe de l’élément de propriété. L’exemple n’utilise pas l’attribut x :Key attribut. Le style est donc implicitement appliqué aux boutons. L’application de styles implicitement ou explicitement est expliquée dans la section suivante.

<Page.Resources>
    <Style TargetType="Button">
        <Setter Property="BorderThickness" Value="5" />
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="BorderBrush" >
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="Yellow" Offset="0.0" />
                    <GradientStop Color="Red" Offset="0.25" />
                    <GradientStop Color="Blue" Offset="0.75" />
                    <GradientStop Color="LimeGreen" Offset="1.0" />
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<StackPanel Orientation="Horizontal">
    <Button Content="Button"/>
    <Button Content="Button"/>
    <Button Content="Button"/>
</StackPanel>

Appliquer un style implicite ou explicite

Si vous définissez un style en tant que ressource, il existe deux façons de l’appliquer à vos contrôles :

  • Implicitement, en spécifiant uniquement un TargetType pour le Style.
  • Explicitement, en spécifiant un TargetType et un attribut x:Key pour le Style, puis en définissant la propriété Style du contrôle cible avec une référence d'extension de balisage {StaticResource} qui utilise la clé explicite.

Si un style contient l’attribut x :Key, vous ne pouvez l’appliquer qu’à un contrôle en définissant la propriété style style du contrôle sur le style clé. En revanche, un style sans attribut x:Key est automatiquement appliqué à chaque contrôle de son type cible, qui n’a pas autrement de paramétrage de style explicite.

Voici deux boutons qui illustrent des styles implicites et explicites.

boutons implicitement et explicitement stylisés.

Dans cet exemple, le premier style a un attribut x :Key et son type cible est Button. La propriété Style du premier bouton est définie sur cette touche. Ce style est donc appliqué explicitement. Le deuxième style est appliqué implicitement au deuxième bouton, car son type cible est Button et le style n’a pas d’attribut x :Key.

<Page.Resources>
    <Style x:Key="PurpleStyle" TargetType="Button">
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Foreground" Value="Purple"/>
    </Style>

    <Style TargetType="Button">
        <Setter Property="FontFamily" Value="Segoe UI"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <RotateTransform Angle="25"/>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Green"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="Foreground" Value="Green"/>
    </Style>
</Page.Resources>

<Grid x:Name="LayoutRoot">
    <Button Content="Button" Style="{StaticResource PurpleStyle}"/>
    <Button Content="Button"/>
</Grid>

Utiliser des styles basés

Pour faciliter la maintenance et la réutilisation des styles, vous pouvez créer des styles qui héritent d’autres styles. Vous utilisez la propriété BasedOn pour créer des styles hérités. Les styles qui héritent d’autres styles doivent cibler le même type de contrôle ou un contrôle qui dérive du type ciblé par le style de base. Par exemple, si un style de base cible ContentControl, les styles basés sur ce style peuvent cibler ContentControl ou des types dérivés de ContentControl , tels que Button et ScrollViewer. Si une valeur n’est pas définie dans le style basé, elle est héritée du style de base. Pour modifier une valeur du style de base, le style basé sur la base remplace cette valeur. L’exemple suivant montre un Bouton et un CheckBox avec des styles qui héritent du même style de base.

boutons stylés utilisant des styles basés sur.

Le style de base cible ContentControl et définit les propriétés Height et Width . Les styles basés sur ce style ciblent CheckBox et Button, lesquels dérivent de ContentControl. Les styles basés définissent différentes couleurs pour les propriétés BorderBrush et Avant-plan. (Vous ne placez généralement pas de bordure autour d’un CheckBox. Nous le faisons ici pour montrer les effets du style.)

<Page.Resources>
    <Style x:Key="BasicStyle" TargetType="ContentControl">
        <Setter Property="Width" Value="130" />
        <Setter Property="Height" Value="30" />
    </Style>

    <Style x:Key="ButtonStyle" TargetType="Button"
           BasedOn="{StaticResource BasicStyle}">
        <Setter Property="BorderBrush" Value="Orange" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Foreground" Value="Red" />
    </Style>

    <Style x:Key="CheckBoxStyle" TargetType="CheckBox"
           BasedOn="{StaticResource BasicStyle}">
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Setter Property="Foreground" Value="Green" />
    </Style>
</Page.Resources>

<StackPanel>
    <Button Content="Button" Style="{StaticResource ButtonStyle}" Margin="0,10"/>
    <CheckBox Content="CheckBox" Style="{StaticResource CheckBoxStyle}"/>
</StackPanel>

Utiliser des outils pour travailler facilement avec des styles

Un moyen rapide d’appliquer des styles à vos contrôles consiste à cliquer avec le bouton droit sur un contrôle sur l’aire de conception XAML de Microsoft Visual Studio, puis à sélectionner Modifier le style ou modifier le modèle (selon le contrôle sur lequel vous cliquez avec le bouton droit). Vous pouvez ensuite appliquer un style existant en sélectionnant Appliquer la ressource ou en définissant un nouveau style en sélectionnant Créer un stylevide. Si vous créez un style vide, vous avez la possibilité de le définir dans la page, dans le fichier App.xaml ou dans un dictionnaire de ressources distinct.

Style léger et aérien

Le remplacement des pinceaux système est généralement effectué au niveau de l’application ou de la page. Dans les deux cas, le remplacement de couleur affecte tous les contrôles qui référencent ce pinceau , et dans XAML, de nombreux contrôles peuvent référencer le même pinceau système.

Capture d’écran de deux boutons : un dans son état de repos et un avec style léger appliqué.

<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.ThemeDictionaries>
            <ResourceDictionary x:Key="Light">
                 <SolidColorBrush x:Key="ButtonBackground" Color="Transparent"/>
                 <SolidColorBrush x:Key="ButtonForeground" Color="MediumSlateBlue"/>
                 <SolidColorBrush x:Key="ButtonBorderBrush" Color="MediumSlateBlue"/>
            </ResourceDictionary>
        </ResourceDictionary.ThemeDictionaries>
    </ResourceDictionary>
</Page.Resources>

Pour les états tels que PointerOver (la souris est pointée sur le bouton), PointerPressé (le bouton a été invité) ou Désactivé (le bouton n'est pas interactif). Les suffixes sont ajoutés aux noms de style léger d'origine : ButtonBackgroundPointerOver, ButtonForegroundPressed, ButtonBorderBrushDisabled, etc. Modifier ces brosses permet également de garantir que vos contrôles sont colorés de manière cohérente avec le thème de votre application.

Le fait de placer ces remplacements de pinceau au niveau App.Resources, modifie tous les boutons de l’application entière, au lieu d’une seule page.

Style par contrôle

Dans d’autres cas, la modification d’un seul contrôle sur une seule page pour ressembler à une certaine façon, sans modifier d’autres versions de ce contrôle, est souhaitée :

Capture d’écran de trois boutons stylisés empilés.

<CheckBox Content="Normal CheckBox" Margin="5"/>
<CheckBox Content="Special CheckBox" Margin="5">
    <CheckBox.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary x:Key="Light">
                    <SolidColorBrush x:Key="CheckBoxForegroundUnchecked"
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxForegroundChecked"
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckGlyphForegroundChecked"
                        Color="White"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundStrokeChecked"  
                        Color="Purple"/>
                    <SolidColorBrush x:Key="CheckBoxCheckBackgroundFillChecked"
                        Color="Purple"/>
                </ResourceDictionary>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </CheckBox.Resources>
</CheckBox>
<CheckBox Content="Normal CheckBox" Margin="5"/>

Cela n’affecterait qu’un « CheckBox spécial » sur la page où ce contrôle existait.

Contrôles personnalisés

Lorsque vous créez vos propres contrôles personnalisés qui peuvent être visuellement et/ou fonctionnellement alignés avec nos contrôles intégrés, envisagez d’utiliser des ressources de style implicites et de style léger pour définir votre contenu personnalisé. Vous pouvez utiliser les ressources directement ou créer un alias pour la ressource.

Utilisation directe des ressources de contrôle

Par exemple, si vous écrivez un contrôle qui ressemble à un bouton, vous pouvez faire référence aux ressources du bouton directement, comme suit :

<Style TargetType="local:MyCustomControl">
  <Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
  <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
</Style>

Aliasing de ressources de contrôle vers de nouveaux noms

Sinon, si vous préférez créer vos propres ressources, vous devez alias ces noms personnalisés à nos ressources de style légères par défaut.

Par exemple, le style de votre contrôle personnalisé peut avoir des définitions de ressources spéciales :

<Style TargetType="local:MyCustomControl">
  <Setter Property="Background" Value="{ThemeResource MyCustomControlBackground}" />
  <Setter Property="BorderBrush" Value="{ThemeResource MyCustomControlBorderBrush}"/>
</Style>

Dans votre dictionnaire de ressources ou définition principale, vous devez raccorder les ressources de style légères à vos ressources personnalisées :

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Default">
        <StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
        <StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
    </ResourceDictionary>        
    <ResourceDictionary x:Key="Light">
        <StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
        <StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
    </ResourceDictionary>
    <ResourceDictionary x:Key="HighContrast">
        <StaticResource x:Key="MyCustomControlBackground" ResourceKey="ButtonBackground" />
        <StaticResource x:Key="MyCustomControlBorderBrush" ResourceKey="ButtonBorderBrush" />
    </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

Il est nécessaire d’utiliser un ThemeDictionary qui est dupliqué trois fois pour gérer correctement les trois modifications de thème différentes (Default, Light, HighContrast).

Avertissement

Si vous affectez une ressource de style léger à un nouvel alias et redéfinissez également la ressource de style Léger, votre personnalisation peut ne pas être appliquée si la recherche de ressources n’est pas dans l’ordre correct. Par exemple, si vous remplacez ButtonBackground dans un endroit qui est recherché avant que MyCustomControlBackground ne soit trouvé, la substitution sera manquée.

Évitez de modifier l'apparence des contrôles

WinUI 2.2 ou version ultérieure inclut de nouveaux styles et modèles pour les contrôles WinUI et système.

La meilleure façon de rester à jour avec nos derniers styles visuels consiste à utiliser le dernier package WinUI 2 et à éviter les styles et modèles personnalisés (également appelés re-templating). Les styles sont toujours un moyen pratique d’appliquer un ensemble de valeurs de manière cohérente entre les contrôles de votre application. Assurez-vous de vous baser sur nos styles les plus récents lorsque vous effectuez cette opération.

Pour les contrôles système qui utilisent des styles WinUI (Windows.UI.Xaml.Controls espace de noms), définissez BasedOn="{StaticResource Default<ControlName>Style}", où <ControlName> est le nom du contrôle. Par exemple:

<Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextBoxStyle}">
    <Setter Property="Foreground" Value="Blue"/>
</Style>

Pour les contrôles WinUI 2 (Microsoft.UI.Xaml.Controls espace de noms), le style par défaut est défini dans les métadonnées. Par conséquent, omettez BasedOn.

Contrôles dérivés

Si vous dérivez un contrôle personnalisé d’un contrôle XAML existant, il n’obtient pas les styles WinUI 2 par défaut. Pour appliquer les styles WinUI 2 :

  • Créez un style avec son TargetType défini sur votre contrôle personnalisé.
  • Basez le style sur le style par défaut du contrôle à partir duquel vous avez dérivé.

Un scénario courant pour cela consiste à dériver un nouveau contrôle de ContentDialog. Cet exemple montre comment créer un nouveau style qui applique DefaultContentDialogStyle à votre boîte de dialogue personnalisée.

<ContentDialog
    x:Class="ExampleApp.SignInContentDialog"
    ... >

    <ContentDialog.Resources>
        <Style TargetType="local:SignInContentDialog" BasedOn="{StaticResource DefaultContentDialogStyle}"/>
        ...
    </ContentDialog.Resources> 
    <!-- CONTENT -->
</ContentDialog>        

Propriété du modèle

Un setter de style peut être utilisé pour la propriété Template d’un contrôle. En fait, cela constitue la majorité d’un style XAML classique et des ressources XAML d’une application. Ceci est abordé plus en détail dans la rubrique modèles de contrôle.