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(); } }
问题原因
- MudDataGrid内部列管理逻辑:当混合静态列与模板内循环生成的动态列时,组件重新渲染时,动态列会被追加到列集合末尾。框架处理模板内的动态内容时,会将新生成的列添加到现有列列表的最后,而非维持模板中的顺序。
- 直接替换数据源并调用
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
相关产品推荐
相关产品推荐

