BootstrapBlazor v10.9.0 已经发布。这个版本的更新集中在两个实际开发中很容易遇到的问题:暗黑主题下筛选组件的显示效果,以及摄像头组件如何明确选择目标设备。
对于已经使用 BootstrapBlazor 构建后台管理系统、数据录入页面或多媒体采集页面的团队来说,这类修复虽然不一定改变 API 规模,却能直接减少主题适配和设备兼容方面的额外代码。
MultiFilter 的暗黑主题支持
筛选器通常位于表格顶部或查询面板中,包含输入框、下拉框、日期选择器和操作按钮。页面切换到暗黑主题后,如果组件仍使用固定的浅色背景、边框或文字颜色,就会出现对比度不足、控件边界不清晰等问题。
v10.9.0 为 MultiFilter 增加了暗黑主题支持。实际使用时,建议让主题状态由应用的统一布局或主题服务管理,而不是在每个筛选器实例中单独判断。
下面是一个可以改造到现有页面中的 Razor 示例。具体参数名称应以项目当前引用的 BootstrapBlazor 版本 API 为准:
@page "/orders"
<PageTitle>订单查询</PageTitle>
<div class="@(darkMode ? "bb-theme-dark" : "bb-theme-light")">
<MultiFilter TValue="OrderQuery" OnSearch="SearchAsync">
<MultiFilterItem TValue="string" Field="CustomerName" Title="客户名称" />
<MultiFilterItem TValue="OrderStatus" Field="Status" Title="订单状态" />
</MultiFilter>
<Table TItem="OrderRow" Items="orders" IsStriped="true" />
</div>
@code {
private bool darkMode = true;
private IEnumerable<OrderRow> orders = Array.Empty<OrderRow>();
private Task SearchAsync(OrderQuery query)
{
// 在这里调用实际的数据查询服务,并更新 orders。
return Task.CompletedTask;
}
private sealed class OrderQuery
{
public string? CustomerName { get; set; }
public OrderStatus? Status { get; set; }
}
private sealed class OrderRow
{
public string Number { get; set; } = string.Empty;
}
private enum OrderStatus
{
Pending,
Completed,
Cancelled
}
}
如果应用使用的是 BootstrapBlazor 自带的主题切换机制,通常不需要额外为 MultiFilter 编写一套暗黑模式 CSS。升级后应重点检查以下场景:
- 筛选项展开菜单中的文字与背景是否有足够对比度。
- 输入框、下拉框和日期控件的边框是否清晰。
- 查询、重置等操作按钮在暗黑背景下是否仍然容易识别。
- 页面首次加载和主题动态切换时,筛选器是否保持一致的视觉状态。
Camera 支持显式指定设备 ID
浏览器可能同时检测到内置摄像头、USB 摄像头、虚拟摄像头或采集卡。仅使用默认设备时,应用无法保证用户选择的是正确的视频来源,尤其是在视频会议、门禁采集、实验室设备和客服坐席等场景中。
v10.9.0 为 Camera 增加了 exact 显式设置设备 ID 的能力。实践中可以先通过浏览器的媒体设备 API 枚举设备,再将用户选中的 deviceId 传给 Camera 组件或对应的媒体约束配置。
下面的 JavaScript 示例可以直接放入 wwwroot/js/camera-devices.js,用于获取摄像头列表:
window.cameraDevices = {
async listVideoInputs() {
// 某些浏览器在用户授权前不会返回完整的设备信息。
await navigator.mediaDevices.getUserMedia({ video: true });
const devices = await navigator.mediaDevices.enumerateDevices();
return devices
.filter(device => device.kind === "videoinput")
.map(device => ({
deviceId: device.deviceId,
label: device.label || "Camera"
}));
}
};
选择设备后,约束参数可以采用下面的形式:
const constraints = {
video: {
deviceId: {
exact: selectedDeviceId
}
},
audio: false
};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
在 Blazor 应用中,建议把设备选择流程设计成三步:
- 页面加载后请求摄像头权限并枚举
videoinput设备。 - 将设备名称显示在下拉框中,让用户明确选择视频来源。
- 将选中的设备 ID 以
exact约束传递给 Camera,并在设备不存在或权限被拒绝时提供降级提示。
需要注意的是,exact 表示必须匹配指定设备。如果设备已经被拔出、浏览器权限发生变化,或者设备 ID 在当前浏览器上下文中不可用,摄像头启动可能失败。因此,生产环境应捕获权限异常和约束不满足异常,并允许用户重新选择设备或回退到默认摄像头。
升级与验证
如果项目通过 NuGet 管理 BootstrapBlazor,可以先更新到目标版本:
dotnet add package BootstrapBlazor --version 10.9.0
dotnet restore
dotnet build
升级后建议在包含以下组合的页面上做一次回归测试:
- 浅色主题和暗黑主题之间动态切换。
MultiFilter中同时存在文本、枚举和日期类型筛选项。- 多个摄像头同时连接时的设备选择。
- 摄像头权限拒绝、设备拔出和浏览器刷新后的恢复流程。
- Chrome、Edge 等目标浏览器中的设备名称和设备 ID 行为。
如果项目锁定了中央包版本,也可以在 Directory.Packages.props 中统一修改:
<Project>
<ItemGroup>
<PackageVersion Include="BootstrapBlazor" Version="10.9.0" />
</ItemGroup>
</Project>
是否值得立即升级
如果应用使用了 MultiFilter,并且已经支持暗黑主题,v10.9.0 的收益比较直接:可以减少筛选器相关的主题覆盖代码。如果应用依赖摄像头采集,并且用户经常需要在多个视频设备之间切换,显式设备 ID 也能让设备选择更加可控。
升级时不应只验证编译是否通过。主题问题通常出现在交互状态中,摄像头问题则常常只在真实硬件、权限变化或设备热插拔时暴露。将这两个场景加入验收清单,才能确认此次更新真正解决了用户会遇到的问题。