Création d’un style pour un contrôle (WPF .NET)

Avec Windows Presentation Foundation (WPF), vous pouvez personnaliser l’apparence d’un contrôle existant avec votre propre style réutilisable. Les styles peuvent être appliqués globalement à votre application, fenêtres et pages, ou directement aux contrôles.

Important

La documentation du Guide du bureau pour .NET 7 et .NET 6 est en cours de construction.

Créer un style

Vous pouvez considérer un Style moyen pratique d’appliquer un ensemble de valeurs de propriété à un ou plusieurs éléments. Vous pouvez utiliser un style sur n’importe quel élément dérivé ou FrameworkElementFrameworkContentElement tel qu’un Window ou un Button.

La façon la plus courante de déclarer un style est une ressource dans la Resources section d’un fichier XAML. Étant donné que les styles sont des ressources, ils obéissent aux mêmes règles d’étendue que celles qui s’appliquent à toutes les ressources. En d’autres termes, lorsque vous déclarez un style affecte l’endroit où le style peut être appliqué. Par exemple, si vous déclarez le style dans l’élément racine de votre fichier XAML de définition d’application, le style peut être utilisé n’importe où dans votre application.

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

Si vous déclarez le style dans l’un des fichiers XAML de l’application, le style ne peut être utilisé que dans ce fichier XAML. Pour plus d’informations sur les règles d’étendue pour les ressources, consultez Vue d’ensemble des ressources XAML.

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

Un style est constitué d’éléments <Setter> enfants qui définissent les propriétés sur les éléments auxquels le style est appliqué. Dans l’exemple ci-dessus, notez que le style est défini pour s’appliquer aux TextBlock types via l’attribut TargetType . Le style définit la FontSize valeur et 15 la valeur FontWeightExtraBold. Ajoutez une <Setter> propriété pour chaque propriété que le style change.

Appliquer implicitement un style

Il Style s’agit d’un moyen pratique d’appliquer un ensemble de valeurs de propriété à plusieurs éléments. Par exemple, considérez les éléments suivants TextBlock et leur apparence par défaut dans une fenêtre.

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Styling sample screenshot before

Vous pouvez modifier l’apparence par défaut en définissant des propriétés, telles que FontSize et FontFamily, sur chaque TextBlock élément directement. Toutefois, si vous souhaitez que vos TextBlock éléments partagent certaines propriétés, vous pouvez créer une Style dans la Resources section de votre fichier XAML, comme illustré ici.

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Lorsque vous définissez le TargetType style sur le TextBlock type et omettez l’attribut x:Key , le style est appliqué à tous les TextBlock éléments délimités au style, ce qui est généralement le fichier XAML lui-même.

TextBlock Les éléments apparaissent maintenant comme suit.

Styling sample screenshot base style

Appliquer un style explicitement

Si vous ajoutez un attribut avec une x:Key valeur au style, le style n’est plus implicitement appliqué à tous les éléments de TargetType. Seuls les éléments qui référencent explicitement le style leur seront appliqués.

Voici le style de la section précédente, mais déclaré avec l’attribut x:Key .

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

Pour appliquer le style, définissez la Style propriété sur l’élément sur la valeur, à l’aide x:Key d’une extension de balisage StaticResource, comme illustré ici.

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Notez que le premier TextBlock élément a le style appliqué à celui-ci alors que le deuxième élément TextBlock reste inchangé. Le style implicite de la section précédente a été remplacé par un style qui a déclaré l’attribut x:Key , ce qui signifie que le seul élément affecté par le style est celui qui a référencé directement le style.

Styling sample screenshot textblock

Une fois qu’un style est appliqué, explicitement ou implicitement, il devient scellé et ne peut pas être modifié. Si vous souhaitez modifier un style appliqué, créez un nouveau style pour remplacer celui existant. Pour plus d'informations, consultez la propriété IsSealed.

Vous pouvez créer un objet qui choisit un style à appliquer selon une logique personnalisée. Pour obtenir un exemple, consultez l’exemple fourni pour la StyleSelector classe.

Appliquer un style par programmation

Pour affecter un style nommé à un élément par programmation, récupérez le style de la collection de ressources et affectez-le à la propriété de l’élément Style . Les éléments d’une collection de ressources sont de type Object. Par conséquent, vous devez convertir le style récupéré en un System.Windows.Style avant de l’affecter à la Style propriété. Par exemple, le code suivant définit le style d’un TextBlock nommé textblock1 au style TitleTextdéfini.

textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)

Étendre un style

Peut-être souhaitez-vous que vos deux TextBlock éléments partagent certaines valeurs de propriété, telles que le FontFamily centre et le HorizontalAlignmentcentre. Mais vous souhaitez également que le texte Mes images ait des propriétés supplémentaires. Vous pouvez le faire en créant un nouveau style basé sur le premier style, comme illustré ici.

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

Ce TextBlock style est maintenant centré, utilise une Comic Sans MS police avec une taille de 26, et la couleur de premier plan définie sur l’exemple LinearGradientBrush indiqué. Notez qu’il remplace la FontSize valeur du style de base. S’il existe plusieurs Setter points vers la même propriété dans un Style, le Setter dernier déclaré est prioritaire.

Les éléments suivants montrent à quoi TextBlock ressemblent les éléments :

Styled TextBlocks

Ce TitleText style étend le style qui a été créé pour le TextBlock type, référencé avec BasedOn="{StaticResource {x:Type TextBlock}}". Vous pouvez également étendre un style qui a un x:Key à l’aide du x:Key style. Par exemple, s’il y avait un style nommé Header1 et que vous vouliez étendre ce style, vous utiliseriez BasedOn="{StaticResource Header1}".

Relation de la propriété TargetType et de l’attribut x :Key

Comme indiqué précédemment, la définition de la TargetType propriété TextBlock sans affecter le style x:Key entraîne l’application du style à tous les TextBlock éléments. Dans ce cas, l’attribut x:Key a implicitement la valeur {x:Type TextBlock}. Cela signifie que si vous définissez explicitement la x:Key valeur sur quelque chose d’autre que {x:Type TextBlock}, l’élément Style n’est pas appliqué automatiquement à tous les TextBlock éléments. Au lieu de cela, vous devez appliquer le style (à l’aide de la x:Key valeur) aux TextBlock éléments explicitement. Si votre style se trouve dans la section ressources et que vous ne définissez pas la TargetType propriété sur votre style, vous devez définir l’attribut x:Key .

En plus de fournir une valeur par défaut pour la x:Keypropriété, la TargetType propriété spécifie le type auquel les propriétés setter s’appliquent. Si vous ne spécifiez pas un TargetType, vous devez qualifier les propriétés dans vos Setter objets avec un nom de classe à l’aide de la syntaxe Property="ClassName.Property". Par exemple, au lieu de définir Property="FontSize", vous devez définir Property sur "TextBlock.FontSize" ou "Control.FontSize".

Notez également que de nombreux contrôles WPF se composent d’une combinaison d’autres contrôles WPF. Si vous créez un style qui s’applique à tous les contrôles d’un type, vous pouvez obtenir des résultats inattendus. Par exemple, si vous créez un style qui cible le TextBlock type dans un Window, le style est appliqué à tous les TextBlock contrôles de la fenêtre, même s’il TextBlock fait partie d’un autre contrôle, tel qu’un ListBox.

Voir aussi