如何在所有继承基类的Razor页面末尾添加组件?
解决方案
方法一:修正BuildRenderTree实现
你之前的问题大概率是RenderTreeBuilder的序列值冲突——基类渲染页面内容时已经占用了部分序列值,重复使用0、1这类小序号会导致新增内容被忽略。另外,直接用AddMarkupContent渲染组件不如直接调用组件渲染方法可靠,改成以下实现:
在ExPageBase中重写BuildRenderTree:
protected override void BuildRenderTree(RenderTreeBuilder builder) { // 先渲染页面本身的内容 base.BuildRenderTree(builder); // 从一个不会和基类冲突的序号开始渲染加载面板 var seq = 1000; builder.OpenComponent<DxLoadingPanel>(seq++); builder.AddAttribute(seq++, nameof(DxLoadingPanel.Visible), Visible); builder.AddAttribute(seq++, nameof(DxLoadingPanel.PositionTarget), "body"); builder.AddAttribute(seq++, nameof(DxLoadingPanel.IsContentBlocked), true); builder.AddAttribute(seq++, nameof(DxLoadingPanel.ApplyBackgroundShading), true); builder.CloseComponent(); }
这样就能确保在页面原有内容之后加载面板,不会因序号冲突被覆盖。
方法二:用全局状态服务配合MainLayout
如果不想修改基类渲染逻辑,可以做一个全局状态管理服务,让页面和布局共享状态:
- 创建状态服务:
public class LoadingStateService { private bool _isLoading; public bool IsLoading { get => _isLoading; set { _isLoading = value; OnStateChanged?.Invoke(); } } public event Action? OnStateChanged; }
在Program.cs里注册为单例:
builder.Services.AddSingleton<LoadingStateService>();
- 修改
MainLayout.razor,注入服务并渲染加载面板:
@inject LoadingStateService LoadingState @implements IDisposable <DxLoadingPanel Visible="@LoadingState.IsLoading" PositionTarget="body" IsContentBlocked="true" ApplyBackgroundShading="true" /> @* 原有布局内容 *@ @Body @code { protected override void OnInitialized() { LoadingState.OnStateChanged += StateHasChanged; } public void Dispose() { LoadingState.OnStateChanged -= StateHasChanged; } }
- 在任意继承自
ExPageBase的页面中注入服务,直接控制加载状态:
@inject LoadingStateService LoadingState // 页面内容 @code { private async Task DoSomething() { LoadingState.IsLoading = true; try { // 执行异步操作 await Task.Delay(2000); } finally { LoadingState.IsLoading = false; } } }
这种方式不用修改页面基类,所有页面都能便捷控制加载状态,避免了布局参数传递的麻烦。
方法三:创建带Razor的抽象基组件
如果ExPageBase允许调整继承链,可以创建一个抽象的Razor基组件,把加载面板逻辑封装进去:
- 创建
ExPageBaseComponent.razor:
@inherits ExPageBase @* 渲染页面内容 *@ @Body <DxLoadingPanel Visible="@Visible" PositionTarget="body" IsContentBlocked="true" ApplyBackgroundShading="true" />
- 让你的页面继承这个Razor组件而非直接继承
ExPageBase:
@page "/User/Search" @inherits ExPageBaseComponent @code { // 页面逻辑 }
这种方式最直观,加载面板代码统一放在基组件里,所有子页面自动继承。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

