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

如何在所有继承基类的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

如果不想修改基类渲染逻辑,可以做一个全局状态管理服务,让页面和布局共享状态:

  1. 创建状态服务:
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>();
  1. 修改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;
    }
}
  1. 在任意继承自ExPageBase的页面中注入服务,直接控制加载状态:
@inject LoadingStateService LoadingState

// 页面内容

@code {
    private async Task DoSomething()
    {
        LoadingState.IsLoading = true;
        try
        {
            // 执行异步操作
            await Task.Delay(2000);
        }
        finally
        {
            LoadingState.IsLoading = false;
        }
    }
}

这种方式不用修改页面基类,所有页面都能便捷控制加载状态,避免了布局参数传递的麻烦。

方法三:创建带Razor的抽象基组件

如果ExPageBase允许调整继承链,可以创建一个抽象的Razor基组件,把加载面板逻辑封装进去:

  1. 创建ExPageBaseComponent.razor:
@inherits ExPageBase

@* 渲染页面内容 *@
@Body

<DxLoadingPanel Visible="@Visible"
                PositionTarget="body"
                IsContentBlocked="true"
                ApplyBackgroundShading="true" />
  1. 让你的页面继承这个Razor组件而非直接继承ExPageBase:
@page "/User/Search"
@inherits ExPageBaseComponent

@code {
    // 页面逻辑
}

这种方式最直观,加载面板代码统一放在基组件里,所有子页面自动继承。

内容的提问来源于stack exchange,提问作者David Thielen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:40:16