共用方式為


將應用程式主題設定為

流覽範例。 流覽範例

.NET 多平臺應用程式 UI (.NET MAUI) 應用程式可以使用標記延伸,在運行 DynamicResource 時間動態響應樣式變更。 這個標記延伸類似於 StaticResource 標記延伸,這兩者都使用字典索引鍵從 ResourceDictionary擷取值。 不過,當標記延伸執行單一字典查閱時 StaticResourceDynamicResource 標記延伸會維護字典索引鍵的連結。 因此,如果已取代與索引鍵相關聯的值,則會將變更套用至 VisualElement。 這可讓運行時間主題在 .NET MAUI 應用程式中實作。

在 .NET MAUI 應用程式中實作運行時間主題的程式如下:

  1. 定義 中 ResourceDictionary每個主題的資源。 如需詳細資訊,請參閱 定義主題
  2. 在應用程式的 App.xaml 檔案中設定預設主題。 如需詳細資訊,請參閱 設定預設主題
  3. 使用標記延伸來取用 DynamicResource 應用程式中的主題資源。 如需詳細資訊,請參閱 取用主題資源
  4. 新增程式代碼以在運行時間載入主題。 如需詳細資訊,請參閱 在運行時間載入主題。

重要

如果您的應用程式不需要在運行時間動態變更主題, StaticResource 請使用標記延伸。 如果您預期在應用程式執行時切換主題,請使用 DynamicResource 標記延伸,以在運行時間更新資源。

下列螢幕快照顯示主題頁面,其中 iOS 應用程式使用淺色主題和 Android 應用程式使用深色主題:

主題應用程式主頁面的螢幕快照。

注意

在運行時間變更主題需要使用 XAML 或 C# 樣式定義,而且無法使用 CSS。

.NET MAUI 也能夠回應系統主題變更。 系統主題可能會因為各種原因而變更,視裝置組態而定。 這包括使用者明確變更的系統主題、由於一天中的時間而變更,以及由於低光等環境因素而變更。 如需詳細資訊,請參閱 響應系統主題變更

定義主題

主題定義為儲存在中的 ResourceDictionary資源物件集合。

下列範例顯示 ResourceDictionary 名為 的 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>

下列範例顯示 ResourceDictionary 名為 之 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>

每個 ResourceDictionary 都包含 Color 定義其個別主題的資源,且每個資源都 ResourceDictionary 使用相同的索引鍵值。 如需資源字典的詳細資訊,請參閱 資源字典

重要

每個 ResourceDictionary都需要檔案後置程序代碼,其會呼叫 InitializeComponent 方法。 這是必要的,如此一來,就可以在運行時間建立代表所選主題的CLR物件。

設定預設主題

應用程式需要默認主題,讓控件具有其取用資源的值。 您可以將主題ResourceDictionary合併為 App.xaml定義的應用程式層級ResourceDictionary,以設定預設主題:

<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>

如需合併資源字典的詳細資訊,請參閱 合併的資源字典

取用主題資源

當應用程式想要取用儲存在 ResourceDictionary 中代表主題的資源時,應該使用 DynamicResource 標記延伸來執行此動作。 這可確保如果在運行時間選取不同的主題,則會套用新主題中的值。

下列範例顯示三種樣式,可套用至應用程式中的所有 Label 物件:

<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>

這些樣式是在應用層級資源字典中定義,以便可供多個頁面取用。 每個樣式都會使用 DynamicResource 標記延伸的主題資源。

這些樣式接著會由頁面取用:

<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>

直接取用主題資源時,應該使用標記延伸來取用 DynamicResource 。 不過,當使用標記延伸的DynamicResource樣式使用時,應該使用標記延伸。StaticResource

如需樣式的詳細資訊,請參閱 使用 XAML 設定應用程式樣式。 如需標記延伸的詳細資訊 DynamicResource ,請參閱 動態樣式

在運行時間載入主題

在執行時間選取主題時,應用程式應該:

  1. 從應用程式移除目前的主題。 這可藉由清除 MergedDictionaries 應用層級 ResourceDictionary的屬性來達成。
  2. 載入選取的主題。 這可藉由將所選主題的實例新增至 MergedDictionaries 應用層級 ResourceDictionary的屬性來達成。

任何 VisualElement 使用 DynamicResource 標記延伸設定屬性的對象,都會套用新的主題值。 這是因為 DynamicResource 標記延伸會維護字典索引鍵的連結。 因此,當取代與索引鍵相關聯的值時,這些變更會套用至 VisualElement 物件。

在範例應用程式中,會透過包含 Picker的強制回應頁面選取主題。 下列程式代碼顯示 OnPickerSelectionChanged 方法,這個方法會在選取的主題變更時執行:

下列範例顯示移除目前的主題並載入新主題:

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