Blazor如何跟随“系统主题”?

[删除(380066935@qq.com或微信通知)]

更好的阅读体验请查看原文:https://www.cnblogs.com/Yu-Core/p/17456389.html

1. 前言

跟随系统主题已经是绝大多数App和网站的标配

但是如何在Blazor中跟随系统主题?

只找到Masa Blazor技术团队发的 MAUI + Masa Blazor 开发界面跟随系统主题切换的App

此方法由于使用 MAUI提供的Application.Current.RequestedTheme来获取系统主题,Application.Current.RequestedThemeChanged来监听系统主题变化,存在一定的局限性

而让Blazor WebAssembly、Blazor Server以及Winform、WPF、Photino.Blazor等支持跟随系统主题,就必须要从Web中入手

搜了一圈,基本上都是用js,window.matchMedia('(prefers-color-scheme:dark)').matches;window.matchMedia('(prefers-color-scheme:dark)').addEventListener

但实际上这种方法获得的是浏览器主题,只不过浏览器主题默认是跟随系统的,所有才会有如此效果。

只能凑合着用了。

2. 添加js

function followSystemTheme(dotNet, callbackMethod) {
    window.matchMedia('(prefers-color-scheme:dark)').addEventListener('change', (e) => {
        dotNet.invokeMethodAsync(callbackMethod, e.matches);
    });
}
function systemIsDarkTheme() {
    return window.matchMedia('(prefers-color-scheme:dark)').matches;
}

3. 调用

[Inject]
private IJSRuntime JS {get;set;} = default!;

bool dark = await JS.InvokeAsync<bool>("systemIsDarkTheme", new object[] { });

var dotNetCallbackRef = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("followSystemTheme", new object[2] { dotNetCallbackRef, "NotifyChanged" });

[JSInvokable]
public void NotifyChanged(bool value)
{
    
}

4. 进阶

如果你想要更便捷的方式,可以使用我已经封装好的包 Yu-Core.BlazorToolkit
大概下面这样,具体用法看README

AppTheme SystemTheme = await Theme.Default.GetSystemThemeAsync();
Theme.Default.SystemThemeChanged += ThemeChanged;