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

.NET 8中MudBlazor MudTable自定义内联编辑失效问题

解决MudTable自定义内联编辑按钮无法触发编辑模式的问题

问题根源分析

  • 自定义编辑按钮传参错误:点击时传递的是table.SelectedItem而非当前行的context,导致目标行无法被正确识别
  • ReadOnly="true"全局禁用了表格的编辑功能,即使调用SetEditingItem也无法生效
  • EditTrigger="TableEditTrigger.EditButton"与自定义按钮逻辑冲突,内置编辑按钮的触发机制会干扰自定义操作
  • OnEditSelected方法中的冗余延迟和置空操作反而导致状态混乱

修正步骤

  1. 移除全局ReadOnly设置:删除MudTable的ReadOnly="true"属性,无需全局禁用编辑(若需默认只读,可在编辑完成后动态设置)
  2. 修改EditTrigger为None:将EditTrigger="TableEditTrigger.EditButton"改为EditTrigger="TableEditTrigger.None",避免内置编辑按钮逻辑干扰
  3. 修正编辑按钮的传参:将OnClick="() => OnEditSelected(table.SelectedItem)"改为OnClick="() => OnEditSelected(context)",传递当前行的上下文对象
  4. 简化OnEditSelected方法:移除不必要的延迟和置空操作,直接设置编辑项并更新状态
  5. 简化SelectedItem绑定:去掉重复的SelectedItem和bind-SelectedItem配置,仅保留SelectedItemChanged处理选中状态

修正后的完整代码

@page "/test/index"
@rendermode InteractiveServer
@attribute [StreamRendering]
@inject ISnackbar Snackbar

<MudTable @ref=@table
          T="Element"
          Items="@elements"
          Hover="true"
          SortLabel="Sort By"
          OnCommitEditClick="@(() => Snackbar.Add("Commit Edit Handler Invoked"))"
          RowEditPreview="BackupItem"
          RowEditCancel="ResetItemToOriginalValues"
          CommitEditIcon=""
          SelectedItemChanged="OnSelectedItemChanged"
          EditTrigger="TableEditTrigger.None"
          >
    <ColGroup>
        <col />
        <col style="width:20%;" />
        <col style="width:50%;" />
        <col style="width:30%" />
    </ColGroup>
    <HeaderContent>
        <MudTh></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Number)">Nr</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel SortBy="new Func<Element, object>(x=>x.Name)">Name</MudTableSortLabel></MudTh>
        <MudTh><MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<Element, object>(x=>x.Age)">Age</MudTableSortLabel></MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd></MudTd>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Name">@context.Name</MudTd>
        <MudTd DataLabel="Age">@context.Age</MudTd>
        <MudTd>
            <MudTooltip Text="Edit">
                <MudIconButton Size="Size.Small" Icon="@Icons.Material.Filled.Edit" OnClick="() => OnEditSelected(context)"></MudIconButton>
            </MudTooltip>
        </MudTd>
    </RowTemplate>
    <RowEditingTemplate>
        <MudTd>
            <div style="display: flex; gap: 10px;">
                <MudTooltip Text="Commit Edit">
                    <MudIconButton Size="Size.Small" Icon="@Icons.Material.Filled.Check" OnClick="OnCommitEditButtonClicked"></MudIconButton>
                </MudTooltip>
                <MudTooltip Text="Cancel Edit">
                    <MudIconButton Size="Size.Small" Icon="@Icons.Material.Filled.Cancel" OnClick="OnCancelEditButtonClicked"></MudIconButton>
                </MudTooltip>
            </div>
        </MudTd>
        <MudTd DataLabel="Nr">@context.Number</MudTd>
        <MudTd DataLabel="Name">
            <MudTextField @bind-Value="@context.Name" Required />
        </MudTd>
        <MudTd DataLabel="Age">
            <MudNumericField @bind-Value="@context.Age" Required />
        </MudTd>
    </RowEditingTemplate>
    <PagerContent>
        <MudTablePager />
    </PagerContent>
</MudTable>

@code {
    private MudTable<Element> table;
    private Element elementBeforeEdit;
    private IEnumerable<Element> elements = new List<Element>();

    protected override void OnInitialized()
    {
        elements = GetData();
    }

    private void OnCommitEditButtonClicked(MouseEventArgs e)
    {
        table.RowEditCommit?.Invoke(table.SelectedItem);
        table.OnCommitEditClick.InvokeAsync(e);
        table.SetEditingItem(null);
        table.SetSelectedItem(null);
    }

    private void OnCancelEditButtonClicked(MouseEventArgs e)
    {
        table.RowEditCancel?.Invoke(table.SelectedItem);
        table.OnCancelEditClick.InvokeAsync(e);
        table.SetEditingItem(null);
        table.SetSelectedItem(null);
    }

    private void OnSelectedItemChanged(Element element)
    {
        elementBeforeEdit = element;
    }

    private void OnEditSelected(Element element)
    {
        table.SetSelectedItem(element);
        table.SetEditingItem(element);
        StateHasChanged();
    }

    private void BackupItem(object element)
    {
        elementBeforeEdit = new()
        {
            Name = ((Element)element).Name,
            Age = ((Element)element).Age,
        };
    }

    private void ResetItemToOriginalValues(object element)
    {
        ((Element)element).Name = elementBeforeEdit.Name;
        ((Element)element).Age = elementBeforeEdit.Age;
    }

    private IEnumerable<Element> GetData()
    {
        return new List<Element>()
        {
            new() { Number = 1, Name = "Peter Parker", Age = 16 },
            new() { Number = 2, Name = "Bruce Wayne", Age = 31 },
            new() { Number = 3, Name = "Clark Kent", Age = 31 },
            new() { Number = 4, Name = "Barry Allen", Age = 29 },
            new() { Number = 5, Name = "Tony Stark", Age = 52 },
        };
    }

    class Element
    {
        public int Number { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

额外说明

  • 编辑完成或取消时,需调用table.SetEditingItem(null)退出编辑模式,仅设置SelectedItem为null无法完全退出编辑状态
  • 若需要默认禁用编辑(仅允许点击自定义按钮进入编辑),可在OnInitialized中设置table.ReadOnly = true,在OnEditSelected中改为table.ReadOnly = false,编辑完成后再改回true

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 20:34:55