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

MudBlazor DataGrid技术问题:如何控制自动生成的保存按钮行为

MudBlazor DataGrid自动生成表单的确认按钮行为控制方案

问题描述

我正在自学MudBlazor,不想再自行处理CSS相关工作,它便捷且功能强大,我非常喜欢!不过遇到一个小问题:当使用DataGrid并基于模型属性自动生成表单时,点击编辑按钮会弹出自动生成的表单,其中包含确认和取消按钮。我想控制自动生成表单中的确认按钮行为——知道可以修改OnClick属性使用自定义函数,但这样自动生成的表单就不会弹出了。希望保留自动生成的表单,仅控制确认按钮的操作:示例中按钮会正确更新List,但我需要将修改后的数据推送到数据库,同时尽量避免遍历300-1000条数据。

原示例代码

@using System.Net.Http.Json 
@using MudBlazor.Examples.Data.Models 
@inject HttpClient httpClient

<MudDataGrid T="Element" Items="@Elements.Take(4)" ReadOnly="@_readOnly" EditMode="@(_isCellEditMode ? DataGridEditMode.Cell : DataGridEditMode.Form)"
    StartedEditingItem="@StartedEditingItem" CanceledEditingItem="@CanceledEditingItem" CommittedItemChanges="@CommittedItemChanges"
    Bordered="true" Dense="true" EditTrigger="@(_editTriggerRowClick ? DataGridEditTrigger.OnRowClick : DataGridEditTrigger.Manual)">
    <Columns>
        <PropertyColumn Property="x => x.Number" Title="Nr" IsEditable="false" />
        <PropertyColumn Property="x => x.Sign" />
        <PropertyColumn Property="x => x.Name" />
        <PropertyColumn Property="x => x.Position">
            <EditTemplate>
                <MudSelect @bind-Value="context.Item.Position" Required RequiredError="You must select a Position!!!" Margin="@Margin.Dense">
                    <MudSelectItem Value="0">zero</MudSelectItem>
                    <MudSelectItem Value="1">one</MudSelectItem>
                    <MudSelectItem Value="17">seventeen</MudSelectItem>
                </MudSelect>
            </EditTemplate>
        </PropertyColumn>
        <PropertyColumn Property="x => x.Molar" Title="Molar mass" />
        <TemplateColumn Hidden="@(_isCellEditMode || _readOnly || _editTriggerRowClick)" CellClass="d-flex justify-end">
            <CellTemplate>
                <MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Edit" OnClick="@context.Actions.StartEditingItemAsync" />
            </CellTemplate>
        </TemplateColumn>
    </Columns> 
</MudDataGrid>

<div class="d-flex flex-wrap mt-4">
    <MudSwitch @bind-Checked="@_readOnly" Color="Color.Primary">Read Only</MudSwitch>
    <div class="d-flex justify-start align-center">
        <p class="mud-typography mud-typography-body1 mud-inherit-text mr-2">Form</p>
        <MudSwitch @bind-Checked="@_isCellEditMode">Cell</MudSwitch>
    </div>
    <div class="d-flex justify-start align-center">
        <p class="mud-typography mud-typography-body1 mud-inherit-text mr-2">Manual</p>
        <MudSwitch @bind-Checked="@_editTriggerRowClick">On Row Click</MudSwitch>
    </div> 
</div>

<MudExpansionPanels Style="flex:1">
    <MudExpansionPanel Text="Show Events">
        @foreach (var message in _events)
        {
            <MudText Typo="@Typo.body2">@message</MudText>
        }
        @if(_events.Count > 0) 
        {
            <div class="d-flex">
                <MudSpacer/>
                <MudButton Class="mt-3" ButtonType="ButtonType.Button" Variant="Variant.Filled" OnClick="@(() => _events.Clear())">Clear</MudButton>
            </div>
        }
    </MudExpansionPanel> 
</MudExpansionPanels>

@code {
    private IEnumerable<Element> Elements = new List<Element>();
    private bool _readOnly;
    private bool _isCellEditMode;
    private List<string> _events = new();
    private bool _editTriggerRowClick;

    protected override async Task OnInitializedAsync()
    {
        Elements = await httpClient.GetFromJsonAsync<List<Element>>("webapi/periodictable");
    }

    void StartedEditingItem(Element item)
    {
        _events.Insert(0, $"Event = StartedEditingItem, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");
    }

    void CanceledEditingItem(Element item)
    {
        _events.Insert(0, $"Event = CanceledEditingItem, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");
    }

    void CommittedItemChanges(Element item)
    {
        _events.Insert(0, $"Event = CommittedItemChanges, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");
    } 
}

解决方案

核心逻辑

直接利用MudDataGrid内置的CommittedItemChanges事件即可——这个事件会在用户点击确认按钮、表单验证通过且数据成功更新到List后触发,传入的参数就是当前修改的那条数据,完全不需要遍历整个数据集,完美匹配需求,同时保留自动生成的表单。

修改步骤

  1. 将CommittedItemChanges方法改为异步(数据库操作通常是异步的),并添加数据库更新逻辑:
// 替换原有的CommittedItemChanges方法
async Task CommittedItemChanges(Element item)
{
    _events.Insert(0, $"Event = CommittedItemChanges, Data = {System.Text.Json.JsonSerializer.Serialize(item)}");
    // 这里添加你的数据库推送逻辑,仅操作当前修改的item
    // 示例:使用EF Core更新数据库
    // await _dbContext.Elements.UpdateAsync(item);
    // await _dbContext.SaveChangesAsync();
}
  1. 同步修改MudDataGrid组件上的事件绑定(Blazor支持异步事件处理):
<!-- 确保CommittedItemChanges绑定的是异步方法 -->
<MudDataGrid T="Element" Items="@Elements.Take(4)" ReadOnly="@_readOnly" EditMode="@(_isCellEditMode ? DataGridEditMode.Cell : DataGridEditMode.Form)"
    StartedEditingItem="@StartedEditingItem" CanceledEditingItem="@CanceledEditingItem" CommittedItemChanges="@CommittedItemChanges"
    Bordered="true" Dense="true" EditTrigger="@(_editTriggerRowClick ? DataGridEditTrigger.OnRowClick : DataGridEditTrigger.Manual)">

额外说明

如果需要在提交前做自定义验证或拦截提交,可以通过自定义EditFormTemplate来实现,但如果只是需要提交后推送数据库,CommittedItemChanges是最简单高效的方案,完全保留自动生成表单的所有默认行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:44:50