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;