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

MudBlazor DataGrid代码添加列始终置于末尾问题排查求助

MudDataGrid动态添加列始终置于末尾的问题排查与解决思路

我在使用MudDataGrid通过代码动态添加列时遇到问题:无论网格原有内容如何,动态添加的列总是排在末尾。点击示例顶部的两个按钮可重现该现象。

问题复现代码

<MudButton OnClick="(()=>LoadDays(10))">Load 10</MudButton>
<MudButton OnClick="(()=>LoadDays(1))">Load 1</MudButton>
<MudDataGrid Class="main-container-grid" Dense=true Height="100%" ColumnsPanelReordering=false DragIndicatorSize=Size.Small T=DateOnly Items=@ListOfDays Hover=true Virtualize=true RowsPerPage=10000 FixedHeader=true Striped=true Bordered=true ColumnResizeMode="ResizeMode.Column">
    <Columns>
        <TemplateColumn Title="employee" StickyLeft=true>
            <CellTemplate>
                xx
            </CellTemplate>
        </TemplateColumn>
        @foreach (DateOnly day in ListOfDays)
        {
            <TemplateColumn Sortable="false" HeaderClass="date-info-header" Class="date-info" CellClass="date-info-cell">
                <HeaderTemplate>
                    <div class="head-content">
                        <div class="day-number">@day.ToString("dd-MM")</div>
                        <div class="day-name">@day.ToString("ddd")</div>
                    </div>
                </HeaderTemplate>
                <CellTemplate>
                    <span>0</span>
                </CellTemplate>
            </TemplateColumn>
        }
    </Columns>
    <NoRecordsContent>
        No data
    </NoRecordsContent>
</MudDataGrid>

@code {
    private List<DateOnly> ListOfDays { get; set; } = new List<DateOnly>();

    private void LoadDays(int count)
    {
        ListOfDays = new List<DateOnly>();
        for (int i = 1; i <= count; i++)
        {
            ListOfDays.Add(DateOnly.FromDateTime(DateTime.Now.AddDays(i)));   
        }
        StateHasChanged();
    }
}

问题原因

  1. MudDataGrid内部列管理逻辑:当混合静态列与模板内循环生成的动态列时,组件重新渲染时,动态列会被追加到列集合末尾。框架处理模板内的动态内容时,会将新生成的列添加到现有列列表的最后,而非维持模板中的顺序。
  2. 直接替换数据源并调用StateHasChanged:这种方式触发组件重新渲染,但框架不会自动维护静态列与动态列的相对顺序,导致动态列始终后置。

解决思路

方案1:通过Columns属性手动构建列集合

放弃在<Columns>模板内写循环,改为绑定Columns属性,手动控制静态列和动态列的顺序,完全掌控列的排列逻辑:

<MudButton OnClick="(()=>LoadDays(10))">Load 10</MudButton>
<MudButton OnClick="(()=>LoadDays(1))">Load 1</MudButton>
<MudDataGrid Class="main-container-grid" Dense=true Height="100%" ColumnsPanelReordering=false DragIndicatorSize=Size.Small T=DateOnly Items=@ListOfDays Hover=true Virtualize=true RowsPerPage=10000 FixedHeader=true Striped=true Bordered=true ColumnResizeMode="ResizeMode.Column" Columns="@_columns">
    <NoRecordsContent>
        No data
    </NoRecordsContent>
</MudDataGrid>

@code {
    private List<DateOnly> ListOfDays { get; set; } = new List<DateOnly>();
    private List<Column<DateOnly>> _columns = new List<Column<DateOnly>>();

    protected override void OnInitialized()
    {
        // 初始化静态列,确保它始终在最前面
        _columns.Add(new TemplateColumn<DateOnly>
        {
            Title = "employee",
            StickyLeft = true,
            CellTemplate = context => @<text>xx</text>
        });
    }

    private void LoadDays(int count)
    {
        ListOfDays = new List<DateOnly>();
        for (int i = 1; i <= count; i++)
        {
            ListOfDays.Add(DateOnly.FromDateTime(DateTime.Now.AddDays(i)));   
        }

        // 保留静态列,清空原有动态列
        var staticColumns = _columns.Where(c => c.Title == "employee").ToList();
        _columns = staticColumns.ToList();

        // 添加动态列,顺序紧跟静态列
        foreach (var day in ListOfDays)
        {
            _columns.Add(new TemplateColumn<DateOnly>
            {
                Sortable = false,
                HeaderClass = "date-info-header",
                Class = "date-info",
                CellClass = "date-info-cell",
                HeaderTemplate = _ => @<div class="head-content">
                    <div class="day-number">@day.ToString("dd-MM")</div>
                    <div class="day-name">@day.ToString("ddd")</div>
                </div>,
                CellTemplate = _ => @<span>0</span>
            });
        }
    }
}

方案2:给列设置Order属性

如果坚持使用模板内循环,可通过给列设置Order属性控制排序。静态列设置较小的Order值,动态列按顺序递增Order值:

<Columns>
    <!-- 静态列设置Order=0,确保优先级最高 -->
    <TemplateColumn Title="employee" StickyLeft=true Order="0">
        <CellTemplate>
            xx
        </CellTemplate>
    </TemplateColumn>
    <!-- 动态列从Order=1开始递增 -->
    @foreach (var (day, index) in ListOfDays.Select((d, i) => (d, i)))
    {
        <TemplateColumn Sortable="false" HeaderClass="date-info-header" Class="date-info" CellClass="date-info-cell" Order="@(index + 1)">
            <HeaderTemplate>
                <div class="head-content">
                    <div class="day-number">@day.ToString("dd-MM")</div>
                    <div class="day-name">@day.ToString("ddd")</div>
                </div>
            </HeaderTemplate>
            <CellTemplate>
                <span>0</span>
            </CellTemplate>
        </TemplateColumn>
    }
</Columns>

MudDataGrid会根据Order值从小到大排列列,这样静态列始终保持在动态列之前。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:24:58