Back to Devexpress

Cell Editing in Blazor Grid

blazor-404756-components-grid-editing-and-validation-edit-modes-edit-cell.md

latest20.0 KB
Original Source

Cell Editing in Blazor Grid

  • Mar 20, 2026
  • 9 minutes to read

In EditCell mode, users can click a data cell to display its in-place editor. When focus moves to another row, the control validates pending user input and saves changes.

Run Demo: Edit CellRun Demo: Edit BatchView Example: Batch Data Editing with Entity Framework Core

The following shortcuts are available in EditCell mode:

Enter or Shift+EnterOpens an in-place editor for the focused cell, if an editor is not already open. If an in-place editor is open, the shortcut applies the changes and closes the editor. Focus can then move to the next cell (Enter) or to the previous cell (Shift+Enter) within the current row or column (see the EnterKeyDirection property).EscWhen a cell editor is visible, a user can press the Esc key to hide the editor and discard changes made in this cell. If the user presses Esc when the editor is hidden, the Grid discards all changes made in the row and cancels row editing.Tab or Shift+TabHides the editor in the current cell, focuses the next or previous data cell, and shows an editor in the newly focused cell.

Video

YouTube video

Enable Editing

Follow the steps below to enable cell editing:

  1. Set the EditMode property to EditCell.

  2. If your data object has a primary key, assign it to the KeyFieldName or KeyFieldNames property.

  3. Handle EditModelSaving and DataItemDeleting events to save changes and reload Grid data. Refer to the following topic for additional information: Edit Model in Blazor Grid.

  4. (Optional) Declare a DxGridCommandColumn object in the Columns template to display the command column.

  5. (Optional). Use the EditNewRowPosition property to display the new item row or change the position of cell editors displayed for new records.

razor
@using Microsoft.EntityFrameworkCore
@inject IDbContextFactory<NorthwindContext> NorthwindContextFactory
@implements IDisposable

<DxGrid Data="Data"
        KeyFieldName="EmployeeId"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        CustomizeEditModel="OnCustomizeEditModel"
        EditMode="GridEditMode.EditCell">
    <Columns>
        <DxGridCommandColumn EditButtonVisible="false" 
                             CancelButtonVisible="false" 
                             SaveButtonVisible="false" />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
</DxGrid>

@code {
    IEnumerable<Employee> Data { get; set; }
    NorthwindContext Northwind { get; set; }

    protected override async Task OnInitializedAsync() {
        Northwind = NorthwindContextFactory.CreateDbContext();
        Data = await Northwind.Employees.ToListAsync();
    }

    void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e) {
        if(e.IsNew) {
            var editModel = (Employee)e.EditModel;
            editModel.EmployeeId = Data.Max(x => x.EmployeeId) + 1;
        }
    }

    async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
        var editModel = (Employee)e.EditModel;
        if (e.IsNew)
            await Northwind.AddAsync(editModel);
        else
            e.CopyChangesToDataItem();
        // Post changes to the database.
        await Northwind.SaveChangesAsync();
        // Reload the entire Grid.
        Data = await Northwind.Employees.ToListAsync();
    }

    async Task OnDataItemDeleting(GridDataItemDeletingEventArgs e) {
        // Remove the data item from the database.
        Northwind.Remove(e.DataItem);
        await Northwind.SaveChangesAsync();
        // Reload the entire Grid.
        Data = await Northwind.Employees.ToListAsync();
    }

    public void Dispose() {
        Northwind?.Dispose();
    }
}
csharp
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Grid.Northwind {
    public partial class Employee {
        public int EmployeeId { get; set; }
        [Required]
        public string LastName { get; set; }
        [Required]
        public string FirstName { get; set; }
        [Required]
        public string Title { get; set; }
        public string TitleOfCourtesy { get; set; }
        public Nullable BirthDate { get; set; }
        [Required]
        [Range(typeof(DateTime), "1/1/2000", "1/1/2020",
        ErrorMessage = "HireDate must be between {1:d} and {2:d}")]
        public Nullable HireDate { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public string HomePhone { get; set; }
        public string Extension { get; set; }
        public byte[] Photo { get; set; }
        public string Notes { get; set; }
        public Nullable<int> ReportsTo { get; set; }
        public string PhotoPath { get; set; }
        public virtual ICollection<Order> Orders { get; set; }
        public string Text => $"{FirstName} {LastName} ({Title})";
        public string ImageFileName => $"Employees/{EmployeeId}.jpg";
    }
}
csharp
using Microsoft.EntityFrameworkCore;
#nullable disable

namespace Grid.Northwind {
    public partial class NorthwindContext : DbContext {

        public NorthwindContext(DbContextOptions<NorthwindContext> options)
            : base(options) {
        }
        // ...
        public virtual DbSet<Employee> Employees { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
            if(!optionsBuilder.IsConfigured) {
                optionsBuilder.UseSqlServer("Server=.\\sqlexpress;Database=Northwind;Integrated Security=true");
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder) {
            modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS");
            // ...
            modelBuilder.Entity<Employee>(entity => {
                entity.HasIndex(e => e.EmployeeId, "EmployeeId");
                entity.HasIndex(e => e.LastName, "LastName");
                entity.HasIndex(e => e.FirstName, "FirstName");
                entity.HasIndex(e => e.Title, "Title");
                entity.HasIndex(e => e.BirthDate, "BirthDate");
                entity.HasIndex(e => e.HireDate, "HireDate");
                entity.HasIndex(e => e.Notes, "Notes");
            });
            OnModelCreatingPartial(modelBuilder);
        }

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}
csharp
using Microsoft.EntityFrameworkCore;
// ...
builder.Services.AddDbContextFactory<NorthwindContext>((sp, options) ={
    var env = sp.GetRequiredService<IWebHostEnvironment>();
    var dbPath = Path.Combine(env.ContentRootPath, "Northwind-5e44b51f.mdf");
    options.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;AttachDbFileName=" + dbPath);
});

Display New Item Row

The new item row is an empty row that allows users to add new records. Set the EditNewRowPosition property to FixedOnTop to display the new item row fixed to the top of the current page. Set this property to LastRow to display this row on the last page after the last data row.

razor
<DxGrid Data="Data"
        KeyFieldName="EmployeeId"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        CustomizeEditModel="OnCustomizeEditModel"
        EditMode="GridEditMode.EditCell"
        EditNewRowPosition="GridEditNewRowPosition.FixedOnTop">
    <Columns>
        *@* ... *@
    </Columns>
</DxGrid>

Users can press Tab or Shift + Tab keys to navigate between the new item row’s data cells. If focus goes beyond the last/first data cell, the Grid focuses the cell on the opposite end and validates user input. Depending on validation results, the following variants are possible:

  • If validation fails, the component displays error icons.
  • If validation succeeds, the component saves changes and starts editing a new row.

Start Editing on Typing

The Grid component starts cell editing after a user clicks a cell or focuses it and presses Enter. Enable the EditOnKeyPress property to additionally enter edit mode once a user starts typing a new value:

razor
<DxGrid Data="Data"
        KeyFieldName="EmployeeId"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        CustomizeEditModel="OnCustomizeEditModel"
        EditMode="GridEditMode.EditCell"
        EditOnKeyPress="true">
    <Columns>
        *@* ... *@
    </Columns>
</DxGrid>

Limitations

The EditCell mode has the following specifics and limitations:

  • The mode is compatible only with DevExpress Blazor editors.
  • The Grid component does not support this mode when you use a Server Mode data source or GridDevExtremeDataSource.
  • The mode requires active keyboard navigation. The Grid component automatically turns on keyboard navigation unless you disable the KeyboardNavigationEnabled property or the DisableKeyboardNavigationInGrid compatibility setting.
  • After a user performs a data shaping operation that hides the edited row from the view (for instance, after a user navigates to the next page), the Grid validates row values. If validation succeeds, the Grid saves changes. If validation fails, the Grid discards changes and displays a notification message: “Unsaved changes were discarded”.
  • During edit operations, the Grid applies user changes only to the edit model and keeps the data item unchanged. To display modified values in the CellDisplayTemplate or DataColumnCellDisplayTemplate, use the edit model’s field values instead of the template context’s DataItem, DisplayText, and Value properties. You can obtain the edit model as follows:
razor
<DxGridDataColumn FieldName="FirstName">
    <CellDisplayTemplate Context="displayContext">
        @{
            string value;
            if (displayContext.Grid.IsEditingRow(displayContext.VisibleIndex)) {
                var editModel = (Employee)displayContext.Grid.GetEditContext().Model;
                value = editModel.FirstName;
            }
            else
                value = displayContext.DisplayText;
        }
        <span>@value</span>
    </CellDisplayTemplate>
</DxGridDataColumn>

This section contains comprehensive editing-related API references.

Show API References

DxGrid API memberTypeDescription
CustomValidatorsPropertyAllows you to declare custom validator components.
DataColumnCellEditTemplatePropertyAllows you to replace automatically generated editors with custom content in all edit cells displayed for data columns.
EditModePropertySpecifies how users edit Grid data.
EditNewRowPositionPropertySpecifies the position of UI elements used to create new rows.
EditOnKeyPressPropertyIn EditCell mode, specifies whether cell editing starts once a user begins typing a new value.
EditorRenderModePropertySpecifies how the Grid renders editors in the filter row and in data rows during edit operations.
ValidationEnabledPropertySpecifies whether the Grid validates user input in DevExpress data editors located in the edit form or edit cells.
CancelEditAsync()MethodCancels row editing and discards changes.
GetColumnEditSettings<T>(String)MethodReturns editor settings of the column bound to the specified data source field.
GetEditContext()MethodReturns the edit context.
IsEditing()MethodReturns whether the Grid is being edited.
IsEditingNewRow()MethodReturns whether a new Grid row is being edited.
IsEditingRow(Int32)MethodReturns whether the specified Grid row is being edited.
SaveChangesAsync()MethodTriggers validation and raises the EditModelSaving event if validation succeeds. The method immediately raises this event if validation is disabled.
ShowDataItemDeleteConfirmation(Object)MethodDisplays the delete confirmation dialog for the specified data item. If a user confirms the operation, the method raises the DataItemDeleting event.
ShowRowDeleteConfirmation(Int32)MethodDisplays the delete confirmation dialog for the specified row. If a user confirms the operation, the method raises the DataItemDeleting event.
StartEditDataItemAsync(Object, String)MethodStarts editing the specified data item.
StartEditNewRowAsync(String)MethodStarts editing a new row.
StartEditRowAsync(Int32, String)MethodStarts editing the row with the specified visible index.
CustomizeDataRowEditorEventAllows you to customize a cell editor in a data row.
CustomizeEditModelEventAllows you to create a custom edit model or customize an automatically generated edit model.
DataItemDeletingEventFires when a user confirms the delete operation in the delete confirmation dialog.
EditCancelingEventFires before the Grid cancels the edit operation and discards changes.
EditModelSavingEventFires if validation succeeds after a user saves changes or you call the SaveChangesAsync() method.
EditStartEventFires before the Grid starts editing a row.
DxGridCommandColumn API memberTypeDescription
CancelButtonVisiblePropertySpecifies whether the command column displays the Cancel button in EditRow or EditCell edit mode.
CellDisplayTemplatePropertySpecifies a template used to display command column cells.
CellEditTemplatePropertySpecifies a template used to display the command column’s edit cell.
DeleteButtonVisiblePropertySpecifies whether the command column displays Delete buttons.
DisplayModePropertySpecifies whether command buttons display icons, captions, or both.
EditButtonVisiblePropertySpecifies whether the command column displays Edit buttons.
HeaderTemplatePropertySpecifies a template used to display the command column header.
NewButtonVisiblePropertySpecifies whether the command column displays the New button.
SaveButtonVisiblePropertySpecifies whether the command column displays the Save button in EditRow or EditCell edit mode.
DxGridDataColumn API memberTypeDescription
CellEditTemplatePropertyAllows you to replace an automatically generated editor with custom content in the column’s edit cell.
DataRowEditorVisiblePropertySpecifies whether to render the editor associated with this column in the column edit cell, edit form, or pop-up edit form.
EditSettingsPropertyAllows you to customize the editor associated with this column.
ReadOnlyPropertySpecifies whether a user can change the column editor value when the Grid is in edit mode.