maui-theming
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese.NET MAUI Theming
.NET MAUI 主题设置
Two main approaches exist for theming MAUI apps: AppThemeBinding (automatic OS theme response) and ResourceDictionary theming (custom themes with runtime switching). They can be combined.
.NET MAUI应用的主题设置主要有两种方法:AppThemeBinding(自动响应系统主题)和ResourceDictionary主题设置(自定义主题并支持运行时切换)。这两种方法可以结合使用。
1. AppThemeBinding (OS Theme Response)
1. AppThemeBinding(响应系统主题)
AppThemeBindingAppThemeBindingProperties
属性
| Property | Description |
|---|---|
| Value used when the device is in light mode |
| Value used when the device is in dark mode |
| Fallback value when the device theme is unknown |
| 属性 | 说明 |
|---|---|
| 设备处于浅色模式时使用的值 |
| 设备处于深色模式时使用的值 |
| 设备主题未知时的回退值 |
XAML Usage
XAML 使用示例
xml
<Label Text="Themed text"
TextColor="{AppThemeBinding Light=Green, Dark=Red}"
BackgroundColor="{AppThemeBinding Light=White, Dark=Black}" />
<!-- With StaticResource or DynamicResource values -->
<Label TextColor="{AppThemeBinding Light={StaticResource LightPrimary},
Dark={StaticResource DarkPrimary}}" />xml
<Label Text="主题化文本"
TextColor="{AppThemeBinding Light=Green, Dark=Red}"
BackgroundColor="{AppThemeBinding Light=White, Dark=Black}" />
<!-- 结合StaticResource或DynamicResource使用 -->
<Label TextColor="{AppThemeBinding Light={StaticResource LightPrimary},
Dark={StaticResource DarkPrimary}}" />C# Extension Methods
C# 扩展方法
csharp
var label = new Label();
// Color-specific helper
label.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);
// Generic helper for any type
label.SetAppTheme<Color>(Label.TextColorProperty, Colors.Green, Colors.Red);csharp
var label = new Label();
// 颜色专用辅助方法
label.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);
// 适用于任意类型的通用辅助方法
label.SetAppTheme<Color>(Label.TextColorProperty, Colors.Green, Colors.Red);2. ResourceDictionary Theming (Custom Themes)
2. ResourceDictionary主题设置(自定义主题)
Use separate files with matching keys to define themes, then swap them at runtime.
ResourceDictionary使用独立的文件,通过匹配的键定义主题,然后在运行时切换这些文件。
ResourceDictionaryDefine Theme Dictionaries
定义主题字典
Each ResourceDictionary must have a code-behind file that calls .
InitializeComponent()LightTheme.xaml
xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Themes.LightTheme">
<Color x:Key="PageBackgroundColor">White</Color>
<Color x:Key="PrimaryTextColor">#333333</Color>
<Color x:Key="AccentColor">#2196F3</Color>
</ResourceDictionary>LightTheme.xaml.cs
csharp
namespace MyApp.Themes;
public partial class LightTheme : ResourceDictionary
{
public LightTheme() => InitializeComponent();
}DarkTheme.xaml.cs — same pattern, different values, same keys.
每个ResourceDictionary必须包含代码后置文件,并调用。
InitializeComponent()LightTheme.xaml
xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Themes.LightTheme">
<Color x:Key="PageBackgroundColor">White</Color>
<Color x:Key="PrimaryTextColor">#333333</Color>
<Color x:Key="AccentColor">#2196F3</Color>
</ResourceDictionary>LightTheme.xaml.cs
csharp
namespace MyApp.Themes;
public partial class LightTheme : ResourceDictionary
{
public LightTheme() => InitializeComponent();
}DarkTheme.xaml.cs —— 遵循相同模式,仅修改值,保持键一致。
Consume with DynamicResource
结合DynamicResource使用
Use (not ) so values update at runtime when the dictionary changes:
DynamicResourceStaticResourcexml
<ContentPage BackgroundColor="{DynamicResource PageBackgroundColor}">
<Label Text="Hello"
TextColor="{DynamicResource PrimaryTextColor}" />
<Button Text="Action"
BackgroundColor="{DynamicResource AccentColor}" />
</ContentPage>使用(而非),这样当字典变化时,值会在运行时自动更新:
DynamicResourceStaticResourcexml
<ContentPage BackgroundColor="{DynamicResource PageBackgroundColor}">
<Label Text="你好"
TextColor="{DynamicResource PrimaryTextColor}" />
<Button Text="操作"
BackgroundColor="{DynamicResource AccentColor}" />
</ContentPage>Switch Themes at Runtime
运行时切换主题
csharp
void ApplyTheme(ResourceDictionary theme)
{
var mergedDictionaries = Application.Current!.Resources.MergedDictionaries;
mergedDictionaries.Clear();
mergedDictionaries.Add(theme);
}
// Usage
ApplyTheme(new LightTheme());
ApplyTheme(new DarkTheme());csharp
void ApplyTheme(ResourceDictionary theme)
{
var mergedDictionaries = Application.Current!.Resources.MergedDictionaries;
mergedDictionaries.Clear();
mergedDictionaries.Add(theme);
}
// 使用示例
ApplyTheme(new LightTheme());
ApplyTheme(new DarkTheme());System Theme Detection
系统主题检测
Current Theme
获取当前主题
csharp
AppTheme currentTheme = Application.Current!.RequestedTheme;
// Returns AppTheme.Light, AppTheme.Dark, or AppTheme.Unspecifiedcsharp
AppTheme currentTheme = Application.Current!.RequestedTheme;
// 返回值为AppTheme.Light、AppTheme.Dark或AppTheme.UnspecifiedOverride the System Theme
覆盖系统主题
csharp
// Force a specific theme regardless of OS setting
Application.Current!.UserAppTheme = AppTheme.Dark;
// Reset to follow the system theme
Application.Current!.UserAppTheme = AppTheme.Unspecified;csharp
// 强制使用特定主题,不受系统设置影响
Application.Current!.UserAppTheme = AppTheme.Dark;
// 重置为跟随系统主题
Application.Current!.UserAppTheme = AppTheme.Unspecified;React to Theme Changes
响应主题变化
csharp
Application.Current!.RequestedThemeChanged += (s, e) =>
{
AppTheme newTheme = e.RequestedTheme;
// Update UI or switch ResourceDictionaries
};csharp
Application.Current!.RequestedThemeChanged += (s, e) =>
{
AppTheme newTheme = e.RequestedTheme;
// 更新UI或切换ResourceDictionaries
};Combining Both Approaches
两种方法结合使用
Use with values for maximum flexibility:
AppThemeBindingDynamicResourcexml
<Label TextColor="{AppThemeBinding
Light={DynamicResource LightPrimary},
Dark={DynamicResource DarkPrimary}}" />Or react to system changes and swap full ResourceDictionaries:
csharp
Application.Current!.RequestedThemeChanged += (s, e) =>
{
ApplyTheme(e.RequestedTheme == AppTheme.Dark
? new DarkTheme()
: new LightTheme());
};将与值结合,实现最大灵活性:
AppThemeBindingDynamicResourcexml
<Label TextColor="{AppThemeBinding
Light={DynamicResource LightPrimary},
Dark={DynamicResource DarkPrimary}}" />或者监听系统主题变化,切换完整的ResourceDictionary:
csharp
Application.Current!.RequestedThemeChanged += (s, e) =>
{
ApplyTheme(e.RequestedTheme == AppTheme.Dark
? new DarkTheme()
: new LightTheme());
};Platform Support & Gotchas
平台支持与注意事项
| Platform | Minimum Version |
|---|---|
| iOS | 13+ |
| Android | 10+ (API 29) |
| macOS Catalyst | 10.14+ |
| Windows | 10+ |
| 平台 | 最低版本 |
|---|---|
| iOS | 13+ |
| Android | 10+ (API 29) |
| macOS Catalyst | 10.14+ |
| Windows | 10+ |
Android: ConfigChanges.UiMode
Android:ConfigChanges.UiMode
MainActivityConfigChanges.UiModecsharp
[Activity(Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize
| ConfigChanges.Orientation
| ConfigChanges.UiMode // Required for theme detection
| ConfigChanges.ScreenLayout
| ConfigChanges.SmallestScreenSize
| ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity { }MainActivityConfigChanges.UiModecsharp
[Activity(Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize
| ConfigChanges.Orientation
| ConfigChanges.UiMode // 主题检测必需
| ConfigChanges.ScreenLayout
| ConfigChanges.SmallestScreenSize
| ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity { }CSS Theming Limitation
CSS主题设置限制
MAUI supports CSS styling, but CSS-based themes cannot be swapped dynamically at runtime. Use ResourceDictionary theming instead for dynamic theme switching.
MAUI支持CSS样式,但基于CSS的主题无法在运行时动态切换。如果需要动态主题切换,请使用ResourceDictionary主题设置方法。
Quick Reference
快速参考
- OS light/dark → markup extension
AppThemeBinding - Theme colors in C# → ,
SetAppThemeColor()SetAppTheme<T>() - Read OS theme →
Application.Current.RequestedTheme - Force theme →
Application.Current.UserAppTheme = AppTheme.Dark - Theme changes → event
RequestedThemeChanged - Custom switching → Swap in
ResourceDictionaryMergedDictionaries - Runtime bindings → (not
DynamicResource)StaticResource
- 系统明暗模式适配 → 标记扩展
AppThemeBinding - C#中设置主题颜色 → 、
SetAppThemeColor()SetAppTheme<T>() - 读取系统主题 →
Application.Current.RequestedTheme - 强制设置主题 →
Application.Current.UserAppTheme = AppTheme.Dark - 监听主题变化 → 事件
RequestedThemeChanged - 自定义主题切换 → 在中替换
MergedDictionariesResourceDictionary - 运行时绑定 → (而非
DynamicResource)StaticResource