You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI Blazor如何为明暗主题设置自动适配的颜色?

.NET MAUI Blazor 适配深色/浅色主题的实现方案

以下是几种实用的主题适配方法,可实现自动跟随系统或手动切换主题的样式效果:

方法一:利用MAUI主题资源+Blazor CSS变量(跟随系统主题)

这种方式让MAUI管理主题资源,Blazor通过CSS变量复用这些资源,自动跟随系统主题切换。

  1. 定义主题颜色资源
    在项目的 Resources/Styles/Colors.xaml 中分别定义浅色、深色模式的颜色:
<Color x:Key="PrimaryLight">#2196F3</Color>
<Color x:Key="PrimaryDark">#1976D2</Color>
<Color x:Key="BackgroundLight">#FFFFFF</Color>
<Color x:Key="BackgroundDark">#121212</Color>
<Color x:Key="TextLight">#333333</Color>
<Color x:Key="TextDark">#EEEEEE</Color>
  1. 映射资源到CSS变量
    在 App.xaml 中通过 CssProperty 将MAUI资源映射为Blazor可识别的CSS变量:
<Application.Resources>
    <ResourceDictionary>
        <!-- 绑定主题资源 -->
        <StaticResource x:Key="Primary" ResourceKey="{AppThemeBinding Light=PrimaryLight, Dark=PrimaryDark}" />
        <StaticResource x:Key="Background" ResourceKey="{AppThemeBinding Light=BackgroundLight, Dark=BackgroundDark}" />
        <StaticResource x:Key="TextColor" ResourceKey="{AppThemeBinding Light=TextLight, Dark=TextDark}" />

        <!-- 映射到CSS变量 -->
        <CssProperty x:Key="--primary-color" Value="{StaticResource Primary}" />
        <CssProperty x:Key="--bg-color" Value="{StaticResource Background}" />
        <CssProperty x:Key="--text-color" Value="{StaticResource TextColor}" />
    </ResourceDictionary>
</Application.Resources>
  1. Blazor中使用CSS变量
    在 wwwroot/css/app.css 里使用这些变量编写样式:
body {
    background-color: var(--bg-color);
    color: var(--text-color);
    margin: 0;
    padding: 1rem;
}

.btn-primary {
    background-color: var(--primary-color);
    color: white;
    border: none;
    padding: 0.5rem 1rem;
    border-radius: 4px;
    cursor: pointer;
}

系统切换主题时,MAUI会自动更新资源值,Blazor的样式会同步变化。

方法二:Blazor CSS媒体查询(纯前端方式)

直接通过CSS的媒体查询监听系统主题偏好,无需依赖MAUI资源配置:

在 wwwroot/css/app.css 中编写如下样式:

/* 浅色模式默认样式 */
body {
    background-color: #FFFFFF;
    color: #333333;
}

.btn-primary {
    background-color: #2196F3;
    color: white;
}

/* 深色模式适配样式 */
@media (prefers-color-scheme: dark) {
    body {
        background-color: #121212;
        color: #EEEEEE;
    }

    .btn-primary {
        background-color: #1976D2;
    }
}

浏览器会自动根据系统的主题偏好应用对应的样式规则。

方法三:手动切换主题+持久化(自定义主题切换)

如果需要让用户手动切换主题并记住选择,可通过Blazor服务+本地存储实现:

  1. 创建主题管理服务
public class ThemeService
{
    public string CurrentTheme { get; set; } = "light";

    public event Action OnThemeChanged;

    public void ToggleTheme()
    {
        CurrentTheme = CurrentTheme == "light" ? "dark" : "light";
        OnThemeChanged?.Invoke();
    }
}

在 Program.cs 中注册服务:

builder.Services.AddScoped<ThemeService>();
  1. 组件中实现主题切换逻辑
    创建一个主题切换组件(比如 ThemeToggle.razor):
@inject ThemeService ThemeService
@implements IDisposable
@inject IJSRuntime JSRuntime

<button @onclick="ToggleTheme" class="btn-primary">切换主题</button>

@code {
    protected override async Task OnInitializedAsync()
    {
        // 从本地存储读取保存的主题
        var savedTheme = await JSRuntime.InvokeAsync<string>("localStorage.getItem", "theme");
        if (!string.IsNullOrEmpty(savedTheme))
        {
            ThemeService.CurrentTheme = savedTheme;
            await UpdateThemeClass();
        }
        ThemeService.OnThemeChanged += UpdateThemeClass;
    }

    private async Task ToggleTheme()
    {
        ThemeService.ToggleTheme();
        // 保存主题到本地存储
        await JSRuntime.InvokeVoidAsync("localStorage.setItem", "theme", ThemeService.CurrentTheme);
    }

    private async Task UpdateThemeClass()
    {
        var body = await JSRuntime.InvokeAsync<IJSObjectReference>("document.getElementsByTagName", "body");
        await body.InvokeVoidAsync("classList.remove", "light", "dark");
        await body.InvokeVoidAsync("classList.add", ThemeService.CurrentTheme);
    }

    public void Dispose()
    {
        ThemeService.OnThemeChanged -= UpdateThemeClass;
    }
}
  1. 编写对应主题类的CSS
    在 wwwroot/css/app.css 中添加类选择器样式:
body.light {
    background-color: #FFFFFF;
    color: #333333;
}

body.dark {
    background-color: #121212;
    color: #EEEEEE;
}

body.light .btn-primary {
    background-color: #2196F3;
}

body.dark .btn-primary {
    background-color: #1976D2;
}

内容的提问来源于stack exchange,提问作者Nidhi Singla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:00:15