Tema di un'app
Le app .NET multipiattaforma dell'interfaccia utente dell'app (.NET MAUI) possono rispondere alle modifiche di stile in modo dinamico in fase di esecuzione usando l'estensione DynamicResource
di markup. Questa estensione di markup è simile all'estensione StaticResource
di markup, in quanto entrambi usano una chiave del dizionario per recuperare un valore da un oggetto ResourceDictionary. Tuttavia, mentre l'estensione StaticResource
di markup esegue una ricerca in un singolo dizionario, l'estensione DynamicResource
di markup mantiene un collegamento alla chiave del dizionario. Pertanto, se il valore associato alla chiave viene sostituito, la modifica viene applicata a VisualElement. Ciò consente l'implementazione del tema di runtime nelle app MAUI .NET.
Il processo di implementazione del tema di runtime in un'app MAUI .NET è il seguente:
- Definire le risorse per ogni tema in un oggetto ResourceDictionary. Per altre informazioni, vedere Definire i temi.
- Impostare un tema predefinito nel file App.xaml dell'app. Per altre informazioni, vedere Impostare un tema predefinito.
- Usare le risorse del tema nell'app usando l'estensione di
DynamicResource
markup. Per altre informazioni, vedere Utilizzare le risorse del tema. - Aggiungere codice per caricare un tema in fase di esecuzione. Per altre informazioni, vedere Caricare un tema in fase di esecuzione.
Importante
Usare l'estensione StaticResource
di markup se l'app non deve modificare i temi in modo dinamico in fase di esecuzione. Se prevedi di cambiare i temi mentre l'app è in esecuzione, usa l'estensione di markup, che consente l'aggiornamento DynamicResource
delle risorse in fase di esecuzione.
Lo screenshot seguente mostra le pagine con tema, con l'app iOS usando un tema chiaro e l'app Android usando un tema scuro:
Nota
La modifica di un tema in fase di esecuzione richiede l'uso di definizioni di stile XAML o C# e non è possibile usare CSS.
.NET MAUI ha anche la possibilità di rispondere alle modifiche dei temi di sistema. Il tema del sistema può cambiare per diversi motivi, a seconda della configurazione del dispositivo. Ciò include il tema di sistema modificato in modo esplicito dall'utente, che cambia a causa dell'ora del giorno e cambia a causa di fattori ambientali come la scarsa illuminazione. Per altre informazioni, vedere Rispondere alle modifiche del tema di sistema.
Definire i temi
Un tema viene definito come una raccolta di oggetti risorsa archiviati in un oggetto ResourceDictionary.
L'esempio seguente mostra un ResourceDictionary oggetto per un tema chiaro denominato 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'esempio seguente mostra un ResourceDictionary oggetto per un tema scuro denominato 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>
Ogni ResourceDictionary contiene Color risorse che definiscono i rispettivi temi, ognuna ResourceDictionary con valori di chiave identici. Per altre informazioni sui dizionari risorse, vedere Dizionari risorse.
Importante
Per ogni ResourceDictionaryoggetto è necessario un file code-behind che chiama il InitializeComponent
metodo . Questa operazione è necessaria in modo che sia possibile creare un oggetto CLR che rappresenta il tema scelto in fase di esecuzione.
Impostare un tema predefinito
Un'app richiede un tema predefinito, in modo che i controlli abbiano valori per le risorse utilizzate. Un tema predefinito può essere impostato unendo il tema ResourceDictionary nel livello ResourceDictionary app definito in 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>
Per altre informazioni sull'unione di dizionari risorse, vedere Dizionari risorse uniti.
Utilizzare le risorse del tema
Quando un'app vuole utilizzare una risorsa archiviata in un ResourceDictionary oggetto che rappresenta un tema, deve farlo con l'estensione DynamicResource
di markup. In questo modo si garantisce che, se in fase di esecuzione è selezionato un tema diverso, verranno applicati i valori del nuovo tema.
L'esempio seguente mostra tre stili da che possono essere applicati a tutti gli Label oggetti nell'app:
<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>
Questi stili vengono definiti nel dizionario risorse a livello di app, in modo che possano essere utilizzati da più pagine. Ogni stile utilizza le risorse del tema con l'estensione di DynamicResource
markup.
Questi stili vengono quindi utilizzati dalle pagine:
<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=" • Cynical but not unfriendly."
Style="{StaticResource SmallLabelStyle}" />
<Label Text=" • Seven varieties of grimaces."
Style="{StaticResource SmallLabelStyle}" />
<Label Text=" • Doesn't laugh at your jokes."
Style="{StaticResource SmallLabelStyle}" />
</StackLayout>
...
</Grid>
</ScrollView>
</ContentPage>
Quando una risorsa del tema viene utilizzata direttamente, deve essere utilizzata con l'estensione di DynamicResource
markup. Tuttavia, quando viene utilizzato uno stile che usa l'estensione DynamicResource
di markup, deve essere utilizzato con l'estensione di StaticResource
markup.
Per altre informazioni sullo stile, vedi App di stile con XAML. Per altre informazioni sull'estensione DynamicResource
di markup, vedere Stili dinamici.
Caricare un tema in fase di esecuzione
Quando un tema viene selezionato in fase di esecuzione, un'app deve:
- Rimuovere il tema corrente dall'app. Questa operazione viene ottenuta cancellando la
MergedDictionaries
proprietà a livello ResourceDictionarydi app. - Caricare il tema selezionato. Questa operazione viene ottenuta aggiungendo un'istanza del tema selezionato alla
MergedDictionaries
proprietà a livello ResourceDictionarydi app.
Tutti VisualElement gli oggetti che impostano le proprietà con l'estensione DynamicResource
di markup applicheranno quindi i nuovi valori del tema. Ciò si verifica perché l'estensione DynamicResource
di markup gestisce un collegamento alle chiavi del dizionario. Pertanto, quando i valori associati alle chiavi vengono sostituiti, le modifiche vengono applicate agli VisualElement oggetti .
Nell'applicazione di esempio viene selezionato un tema tramite una pagina modale che contiene un oggetto Picker. Il codice seguente mostra il OnPickerSelectionChanged
metodo , che viene eseguito quando cambia il tema selezionato:
L'esempio seguente mostra la rimozione del tema corrente e il caricamento di un nuovo tema:
ICollection<ResourceDictionary> mergedDictionaries = Application.Current.Resources.MergedDictionaries;
if (mergedDictionaries != null)
{
mergedDictionaries.Clear();
mergedDictionaries.Add(new DarkTheme());
}