Partager via


Appliquer un thème à une application

Parcourez l’exemple. Parcourir l'exemple

Les applications .NET Multi-Platform App UI (.NET MAUI) peuvent répondre aux modifications de style dynamiquement au moment du runtime à l’aide de l’extension de balisage DynamicResource. L’extension de balisage est similaire à l’extension de balisage StaticResource, dans la mesure où les deux utilisent une clé de dictionnaire pour extraire une valeur d’un ResourceDictionary. Toutefois, alors que l’extension de balisage StaticResource effectue une seule recherche dans le dictionnaire, l’extension DynamicResource conserve un lien vers la clé de dictionnaire. Par conséquent, si la valeur associée à la clé est remplacée, la modification est appliquée au VisualElement. Cela permet d’implémenter les thèmes de runtime dans les applications .NET MAUI.

Le processus d’implémentation de thèmes de runtime dans une application MAUI .NET est le suivant :

  1. Définissez les ressources de chaque thème dans un ResourceDictionary. Pour plus d’informations, consultez Définir des thèmes.
  2. Définissez un thème par défaut dans le fichier App.xaml de l’application. Pour plus d’informations, consultez Définir un thème par défaut.
  3. Consommez des ressources de thème dans l’application à l’aide de l’extension de balisage DynamicResource. Pour plus d’informations, consultez Consommer des ressources de thème.
  4. Ajoutez du code pour charger un thème au moment du runtime. Pour plus d’informations, consultez Charger un thème au moment du runtime.

Important

Utilisez l’extension de balisage StaticResource si votre application n’a pas besoin de modifier dynamiquement les thèmes au moment du runtime. Si vous prévoyez de changer de thème pendant l’exécution de l’application, utilisez l’extension de balisage DynamicResource, ce qui permet de mettre à jour les ressources au moment du runtime.

La capture d’écran suivante montre des pages ou un thème a été appliqué, avec l’application iOS à l’aide d’un thème clair et de l’application Android à l’aide d’un thème sombre :

Capture d’écran de la page principale d’une application à thème.

Remarque

La modification d’un thème au moment du runtime nécessite l’utilisation de définitions de style XAML ou C# et n’est pas possible à l’aide de CSS.

.NET MAUI a également la possibilité de répondre aux modifications appportées à un thème de système. Le thème système peut changer pour diverses raisons, en fonction de la configuration de l’appareil. Le thème système peut notamment être modifié explicitement par l’utilisateur ou changer en fonction de l’heure de la journée ou de facteurs environnementaux tels qu’une faible lumière. Pour plus d’informations, consultez Répondre à des modifications apportées à un thème de système.

Définir des thèmes

Un thème est défini comme une collection d’objets de ressources stockés dans un ResourceDictionary.

L’exemple suivant montre un ResourceDictionary pour un thème clair nommé LightTheme :

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.LightTheme">
    <Color x:Key="PageBackgroundColor">White</Color>
    <Color x:Key="NavigationBarColor">WhiteSmoke</Color>
    <Color x:Key="PrimaryColor">WhiteSmoke</Color>
    <Color x:Key="SecondaryColor">Black</Color>
    <Color x:Key="PrimaryTextColor">Black</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">Gray</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

L’exemple suivant montre un ResourceDictionary pour un thème sombre nommé DarkTheme :

<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ThemingDemo.DarkTheme">
    <Color x:Key="PageBackgroundColor">Black</Color>
    <Color x:Key="NavigationBarColor">Teal</Color>
    <Color x:Key="PrimaryColor">Teal</Color>
    <Color x:Key="SecondaryColor">White</Color>
    <Color x:Key="PrimaryTextColor">White</Color>
    <Color x:Key="SecondaryTextColor">White</Color>
    <Color x:Key="TertiaryTextColor">WhiteSmoke</Color>
    <Color x:Key="TransparentColor">Transparent</Color>
</ResourceDictionary>

Chaque ResourceDictionary contient des ressources Color qui définissent leurs thèmes respectifs, chaque ResourceDictionary utilisant des valeurs de clé identiques. Pour obtenir plus d’informations sur les dictionnaires de ressources, consultez Dictionnaires de ressources.

Important

Un fichier code-behind est requis pour chaque ResourceDictionary, qui appelle la méthode InitializeComponent. Cela est nécessaire afin qu’un objet CLR représentant le thème choisi puisse être créé au moment du runtime.

Définir un thème par défaut

Une application requiert un thème par défaut afin que les contrôles aient des valeurs pour les ressources qu’ils consomment. Un thème par défaut peut être défini en fusionnant le ResourceDictionary du thème dans le ResourceDictionary au niveau de l’application défini dans App.xaml :

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>
        <ResourceDictionary Source="Themes/LightTheme.xaml" />
    </Application.Resources>
</Application>

Pour obtenir plus d’informations sur le fusionnement des dictionnaires de ressources, consultez Dictionnaires de ressources fusionnés.

Consommer des ressources de thème

Lorsqu’une application souhaite consommer une ressource stockée dans un ResourceDictionary qui représente un thème, elle doit le faire avec l’extension de balisage DynamicResource. Cela garantit que si un thème différent est sélectionné au moment du runtime, les valeurs du nouveau thème seront appliquées.

L’exemple suivant montre trois styles qui peuvent être appliqués à tous les objets Label dans l’application :

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ThemingDemo.App">
    <Application.Resources>

        <Style x:Key="LargeLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource SecondaryTextColor}" />
            <Setter Property="FontSize"
                    Value="30" />
        </Style>

        <Style x:Key="MediumLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource PrimaryTextColor}" />
            <Setter Property="FontSize"
                    Value="25" />
        </Style>

        <Style x:Key="SmallLabelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{DynamicResource TertiaryTextColor}" />
            <Setter Property="FontSize"
                    Value="15" />
        </Style>

    </Application.Resources>
</Application>

Ces styles sont définis dans le dictionnaire de ressources au niveau de l’application, afin qu’ils puissent être consommés par plusieurs pages. Chaque style utilise des ressources de thème avec l’extension de balisage DynamicResource.

Ces styles sont ensuite consommés par les pages :

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ThemingDemo"
             x:Class="ThemingDemo.UserSummaryPage"
             Title="User Summary"
             BackgroundColor="{DynamicResource PageBackgroundColor}">
    ...
    <ScrollView>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="200" />
                <RowDefinition Height="120" />
                <RowDefinition Height="70" />
            </Grid.RowDefinitions>
            <Grid BackgroundColor="{DynamicResource PrimaryColor}">
                <Label Text="Face-Palm Monkey"
                       VerticalOptions="Center"
                       Margin="15"
                       Style="{StaticResource MediumLabelStyle}" />
                ...
            </Grid>
            <StackLayout Grid.Row="1"
                         Margin="10">
                <Label Text="This monkey reacts appropriately to ridiculous assertions and actions."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Cynical but not unfriendly."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Seven varieties of grimaces."
                       Style="{StaticResource SmallLabelStyle}" />
                <Label Text="  &#x2022; Doesn't laugh at your jokes."
                       Style="{StaticResource SmallLabelStyle}" />
            </StackLayout>
            ...
        </Grid>
    </ScrollView>
</ContentPage>

Lorsqu’une ressource de thème est consommée directement, elle doit être consommée avec l’extension de balisage DynamicResource. Toutefois, lorsqu’un style qui utilise l’extension de balisage DynamicResource est consommé, il doit être consommé avec l’extension de balisage StaticResource.

Pour plus d’informations sur les styles, consultez Appliquer un style aux applications en utilisant XAML. Pour plus d’informations sur l’extension de balisage DynamicResource, consultez Styles dynamiques.

Charger un thème au moment du runtime

Lorsqu’un thème est sélectionné au moment du runtime, une application doit :

  1. Supprimer le thème actuel de l’application. Pour ce faire, effacez la propriété MergedDictionaries du ResourceDictionary au niveau de l’application.
  2. Charger le thème sélectionné. Pour ce faire, ajoutez une instance du thème sélectionné à la propriété MergedDictionaries du ResourceDictionary au niveau de l’application.

Tous les objets VisualElement qui définissent des propriétés avec l’extension de balisage DynamicResource appliquent ensuite les nouvelles valeurs de thème. Cela se produit parce que l’extension de balisage DynamicResource conserve un lien vers des clés de dictionnaire. Par conséquent, lorsque les valeurs associées aux clés sont remplacées, les modifications sont appliquées aux objets VisualElement.

Dans l’exemple d’application, un thème est sélectionné via une page modale qui contient un Picker. Le code suivant montre la méthode OnPickerSelectionChanged, qui est exécutée lorsque le thème sélectionné change :

L’exemple suivant montre comment supprimer le thème actuel et charger un nouveau thème :

ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
    mergedDictionaries.Clear();
    mergedDictionaries.Add(new DarkTheme());
}