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

在Blazor (.razor)组件中定义多个Panel RenderFragment的实现方法

实现方案

步骤1:定义所需枚举

先声明业务需要的两个枚举类型:

public enum Layout
{
    GridView,
    ListView,
    DisplayView
}

public enum PanelType
{
    Display,
    Grid,
    List
}

步骤2:创建子Panel组件

新建Panel.razor组件,作为参数容器,不需要额外渲染逻辑,仅用于承载每个Panel的独有参数和内容:

@code {
    // 接收父级GroupPanel的级联注入
    [CascadingParameter]
    private GroupPanel ParentGroupPanel { get; set; }

    // 公共参数
    [Parameter]
    public Layout Layout { get; set; }
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    // 可根据不同Layout的需求扩展独有参数,例如:
    // GridView专属列配置
    [Parameter]
    public List<GridColumn> GridColumns { get; set; }
    // ListView专属行高配置
    [Parameter]
    public int ListRowHeight { get; set; }

    protected override void OnInitialized()
    {
        // 初始化时将当前Panel实例注册到父组件
        ParentGroupPanel?.RegisterPanel(this);
    }
}

步骤3:实现父GroupPanel组件

新建GroupPanel.razor组件,通过级联参数收集所有子Panel实例,实现自定义渲染逻辑:

<!-- 级联传递当前GroupPanel实例,供子Panel注册使用 -->
<CascadingValue Value="this" IsFixed="true">
    @ChildContent
</CascadingValue>

<!-- 以下为示例渲染逻辑,可根据业务需求调整 -->
<!-- 示例1:根据PanelType渲染对应Panel -->
@if (CurrentDisplayPanel != null)
{
    <div class="group-panel-container">
        @CurrentDisplayPanel.ChildContent
    </div>
}

<!-- 示例2:同时渲染所有Panel,可按需开启 -->
@*
@foreach (var panel in AllPanels)
{
    <div class="panel-item" data-layout="@panel.Layout">
        @panel.ChildContent
    </div>
}
*@

@code {
    private readonly List<Panel> _panelList = new();
    private Panel CurrentDisplayPanel { get; set; }

    [Parameter]
    public PanelType PanelType { get; set; }
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    // 对外暴露只读的Panel列表
    public IReadOnlyList<Panel> AllPanels => _panelList.AsReadOnly();

    // 供子Panel调用的注册方法
    public void RegisterPanel(Panel panel)
    {
        if (!_panelList.Contains(panel))
        {
            _panelList.Add(panel);
            // 初始化时根据PanelType匹配要展示的Panel
            CurrentDisplayPanel = _panelList.FirstOrDefault(p => p.Layout == MapPanelTypeToLayout(PanelType));
        }
    }

    // 自定义PanelType到Layout的映射逻辑,可按需调整
    private Layout MapPanelTypeToLayout(PanelType panelType)
    {
        return panelType switch
        {
            PanelType.Display => Layout.DisplayView,
            PanelType.Grid => Layout.GridView,
            PanelType.List => Layout.ListView,
            _ => throw new ArgumentOutOfRangeException(nameof(panelType))
        };
    }
}

调用方式

和你期望的写法完全一致:

<GroupPanel PanelType="PanelType.Display">
    <Panel Layout="Layout.GridView">
        <!-- GridView对应的内容 -->
    </Panel>
    <Panel Layout="Layout.ListView">
        <!-- ListView对应的内容 -->
    </Panel>
    <Panel Layout="Layout.DisplayView">
        <!-- DisplayView对应的内容 -->
    </Panel>
</GroupPanel>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:57:02