Cell Editing in Blazor Data Grid

Cell editing provides a streamlined way to update individual cell values directly within the Blazor DataGrid. Cell editing is designed for quick, inline modifications, making data entry and corrections more efficient. Cell editing ensures that changes are applied seamlessly to large datasets while maintaining consistency with the Data Grid’s overall editing experience.

In enterprise applications, users often need to correct a few values across a large dataset. Opening a separate edit form for each change adds unnecessary steps and interrupts the workflow. Cell editing streamlines these corrections, reduces repetitive steps, and boosts productivity.

Common pain points

  • Repeated clicks and form openings to update individual values.
  • Context switching between the Data Grid and separate edit forms.
  • Slower corrections when changes span many records.

Enable cell editing

To enable cell editing in the Data Grid, configure the GridEditSettings component. Set the Mode property to EditMode.Cell. Set the AllowEditing property to true to permit cell updates.

With both properties configured, double-clicking a cell, or selecting a cell and pressing enter or F2, switches that cell into edit mode.

@using Syncfusion.Blazor.Grids

<SfGrid DataSource="@OrderData" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })" Height="315">
    <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" Mode="EditMode.Cell"></GridEditSettings>
    <GridColumns>
        <GridColumn Field=@nameof(OrderDetails.OrderID) HeaderText="Order ID" IsPrimaryKey="true" ValidationRules="@(new ValidationRules{ Required=true})" TextAlign="TextAlign.Right" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.CustomerID) HeaderText="Customer Name" ValidationRules="@(new ValidationRules{ Required=true, MinLength=5})" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.Freight) HeaderText="Freight" ValidationRules="@(new ValidationRules{ Required=true, Min=1, Max=1000})" Format="C2" TextAlign="TextAlign.Right" EditType="EditType.NumericEdit" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.ShipCountry) HeaderText="Ship Country" EditType="EditType.DropDownEdit" Width="150"></GridColumn>
    </GridColumns>
</SfGrid>

@code {
    public List<OrderDetails> OrderData { get; set; }
    protected override void OnInitialized()
    {
        OrderData = OrderDetails.GetAllRecords();
    }
}
public class OrderDetails
{
    public static List<OrderDetails> Order = new List<OrderDetails>();
    public OrderDetails() { }
    public OrderDetails(int OrderID, string CustomerId, double Freight, string ShipCountry)
    {
        this.OrderID = OrderID;
        this.CustomerID = CustomerId;
        this.Freight = Freight;
        this.ShipCountry = ShipCountry;    
    }
    public static List<OrderDetails> GetAllRecords()
    {
        if (Order.Count == 0)
        {
            Order.Add(new OrderDetails(10248, "VINET", 32.38, "France"));
            Order.Add(new OrderDetails(10249, "TOMSP", 11.61, "Germany"));
            Order.Add(new OrderDetails(10250, "HANAR", 65.83, "Brazil"));
            Order.Add(new OrderDetails(10251, "VICTE", 41.34, "France"));
            Order.Add(new OrderDetails(10252, "SUPRD", 51.3, "Belgium"));
            Order.Add(new OrderDetails(10253, "HANAR", 58.17, "Brazil"));
            Order.Add(new OrderDetails(10254, "CHOPS", 22.98, "Switzerland"));
            Order.Add(new OrderDetails(10255, "RICSU", 148.33, "Switzerland"));
            Order.Add(new OrderDetails(10256, "WELLI", 13.97, "Brazil"));
            Order.Add(new OrderDetails(10257, "HILAA", 81.91, "Venezuela"));
            Order.Add(new OrderDetails(10258, "ERNSH", 140.51, "Austria"));
            Order.Add(new OrderDetails(10259, "CENTC", 3.25, "Mexico"));
            Order.Add(new OrderDetails(10260, "OTTIK", 55.09, "Germany"));
            Order.Add(new OrderDetails(10261, "QUEDE", 3.05, "Brazil"));
            Order.Add(new OrderDetails(10262, "RATTC", 48.29, "USA"));
        }
        return Order;
    }
    public int OrderID { get; set; }
    public string CustomerID { get; set; }
    public double Freight { get; set; }
    public string ShipCountry { get; set; }
}

When editing is enabled, the IsPrimaryKey property must be set to true on the unique column so that updates are mapped to the correct record.

Edit on key press in cell editing

Edit on key press allows a selected cell to enter edit mode immediately when a user presses a printable key, without requiring a double-click or another action to start editing. Edit on key press improves data-entry speed and reduces unnecessary interactions, making it ideal for applications where users frequently update large amounts of data. Typical use cases include inventory updates, order management, time sheet tracking, and other spreadsheet-style data entry scenarios.

To enable, set the AllowEditOnKeyPress property in GridEditSettings to true. When enabled, pressing a printable character key, such as a letter, digit, or symbol, while a cell is selected, automatically places the cell in edit mode and applies the entered character directly to the cell.

@using Syncfusion.Blazor.Grids

<SfGrid DataSource="@OrderData" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })" Height="315">
    <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" Mode="EditMode.Cell" AllowEditOnKeyPress="true"></GridEditSettings>
    <GridColumns>
        <GridColumn Field=@nameof(OrderDetails.OrderID) HeaderText="Order ID" IsPrimaryKey="true" ValidationRules="@(new ValidationRules{ Required=true})" TextAlign="TextAlign.Right" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.CustomerID) HeaderText="Customer Name" ValidationRules="@(new ValidationRules{ Required=true, MinLength=5})" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.Freight) HeaderText="Freight" ValidationRules="@(new ValidationRules{ Required=true, Min=1, Max=1000})" Format="C2" TextAlign="TextAlign.Right" EditType="EditType.NumericEdit" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.ShipCountry) HeaderText="Ship Country" EditType="EditType.DropDownEdit" Width="150"></GridColumn>
    </GridColumns>
</SfGrid>

@code {
    public List<OrderDetails> OrderData { get; set; }
    protected override void OnInitialized()
    {
        OrderData = OrderDetails.GetAllRecords();
    }
}
public class OrderDetails
{
    public static List<OrderDetails> Order = new List<OrderDetails>();
    public OrderDetails() { }
    public OrderDetails(int OrderID, string CustomerId, double Freight, string ShipCountry)
    {
        this.OrderID = OrderID;
        this.CustomerID = CustomerId;
        this.Freight = Freight;
        this.ShipCountry = ShipCountry;    
    }
    public static List<OrderDetails> GetAllRecords()
    {
        if (Order.Count == 0)
        {
            Order.Add(new OrderDetails(10248, "VINET", 32.38, "France"));
            Order.Add(new OrderDetails(10249, "TOMSP", 11.61, "Germany"));
            Order.Add(new OrderDetails(10250, "HANAR", 65.83, "Brazil"));
            Order.Add(new OrderDetails(10251, "VICTE", 41.34, "France"));
            Order.Add(new OrderDetails(10252, "SUPRD", 51.3, "Belgium"));
            Order.Add(new OrderDetails(10253, "HANAR", 58.17, "Brazil"));
            Order.Add(new OrderDetails(10254, "CHOPS", 22.98, "Switzerland"));
            Order.Add(new OrderDetails(10255, "RICSU", 148.33, "Switzerland"));
            Order.Add(new OrderDetails(10256, "WELLI", 13.97, "Brazil"));
            Order.Add(new OrderDetails(10257, "HILAA", 81.91, "Venezuela"));
            Order.Add(new OrderDetails(10258, "ERNSH", 140.51, "Austria"));
            Order.Add(new OrderDetails(10259, "CENTC", 3.25, "Mexico"));
            Order.Add(new OrderDetails(10260, "OTTIK", 55.09, "Germany"));
            Order.Add(new OrderDetails(10261, "QUEDE", 3.05, "Brazil"));
            Order.Add(new OrderDetails(10262, "RATTC", 48.29, "USA"));
        }
        return Order;
    }
    public int OrderID { get; set; }
    public string CustomerID { get; set; }
    public double Freight { get; set; }
    public string ShipCountry { get; set; }
}

Customize enter key navigation

EnterKeyDirection is a GridEditSettings property that controls where focus moves after saving a cell using the enter key. The property supports keyboard-based data entry scenarios that require quick navigation between cells without using the mouse. By default, the value is EnterKeyDirection.None, which keeps the focus on the current cell.

The EnterKeyDirection enumeration provides the following options:

Enum value Description
EnterKeyDirection.NextColumn Moves focus to the next column in the current row. Useful for entering data across a row.
EnterKeyDirection.NextRow Moves focus to the same column in the next row. Useful for updating the same field across multiple records.
EnterKeyDirection.None Keeps focus on the current cell after saving. Useful for reviewing or correcting the entered value.
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.DropDowns

<label>Enter Key Direction</label>
<SfDropDownList DataSource="@EnterDirectionOptions"
                @bind-Value="SelectedEnterDirection"
                TValue="EnterKeyDirection"
                TItem="DropdownOption<EnterKeyDirection>"
                PopupHeight="200px"
                Width="150px">
    <DropDownListFieldSettings Text="Label" Value="Value"></DropDownListFieldSettings>
</SfDropDownList>

<SfGrid DataSource="@OrderData" Toolbar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" })" Height="315">
    <GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" Mode="EditMode.Cell" EnterKeyDirection="@SelectedEnterDirection"></GridEditSettings>
    <GridColumns>
        <GridColumn Field=@nameof(OrderDetails.OrderID) HeaderText="Order ID" IsPrimaryKey="true" ValidationRules="@(new ValidationRules{ Required=true})" TextAlign="TextAlign.Right" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.CustomerID) HeaderText="Customer Name" ValidationRules="@(new ValidationRules{ Required=true, MinLength=5})" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.Freight) HeaderText="Freight" ValidationRules="@(new ValidationRules{ Required=true, Min=1, Max=1000})" Format="C2" TextAlign="TextAlign.Right" EditType="EditType.NumericEdit" Width="120"></GridColumn>
        <GridColumn Field=@nameof(OrderDetails.ShipCountry) HeaderText="Ship Country" EditType="EditType.DropDownEdit" Width="150"></GridColumn>
    </GridColumns>
</SfGrid>

@code
{
    public List<OrderDetails> OrderData { get; set; }
    private EnterKeyDirection SelectedEnterDirection { get; set; } = EnterKeyDirection.NextRow;

    private List<DropdownOption<EnterKeyDirection>> EnterDirectionOptions { get; set; } = new List<DropdownOption<EnterKeyDirection>>
    {
        new DropdownOption<EnterKeyDirection> { Label = "None", Value = EnterKeyDirection.None },
        new DropdownOption<EnterKeyDirection> { Label = "NextRow", Value = EnterKeyDirection.NextRow },
        new DropdownOption<EnterKeyDirection> { Label = "NextColumn", Value = EnterKeyDirection.NextColumn }
    };

    protected override void OnInitialized()
    {
        OrderData = OrderDetails.GetAllRecords();
    }
}
public class OrderDetails
{
    public static List<OrderDetails> Order = new List<OrderDetails>();
    public OrderDetails() { }
    public OrderDetails(int OrderID, string CustomerId, double Freight, string ShipCountry)
    {
        this.OrderID = OrderID;
        this.CustomerID = CustomerId;
        this.Freight = Freight;
        this.ShipCountry = ShipCountry;
    }
    public static List<OrderDetails> GetAllRecords()
    {
        if (Order.Count == 0)
        {
            Order.Add(new OrderDetails(10248, "VINET", 32.38, "France"));
            Order.Add(new OrderDetails(10249, "TOMSP", 11.61, "Germany"));
            Order.Add(new OrderDetails(10250, "HANAR", 65.83, "Brazil"));
            Order.Add(new OrderDetails(10251, "VICTE", 41.34, "France"));
            Order.Add(new OrderDetails(10252, "SUPRD", 51.3, "Belgium"));
            Order.Add(new OrderDetails(10253, "HANAR", 58.17, "Brazil"));
            Order.Add(new OrderDetails(10254, "CHOPS", 22.98, "Switzerland"));
            Order.Add(new OrderDetails(10255, "RICSU", 148.33, "Switzerland"));
            Order.Add(new OrderDetails(10256, "WELLI", 13.97, "Brazil"));
            Order.Add(new OrderDetails(10257, "HILAA", 81.91, "Venezuela"));
            Order.Add(new OrderDetails(10258, "ERNSH", 140.51, "Austria"));
            Order.Add(new OrderDetails(10259, "CENTC", 3.25, "Mexico"));
            Order.Add(new OrderDetails(10260, "OTTIK", 55.09, "Germany"));
            Order.Add(new OrderDetails(10261, "QUEDE", 3.05, "Brazil"));
            Order.Add(new OrderDetails(10262, "RATTC", 48.29, "USA"));
        }
        return Order;
    }
    public int OrderID { get; set; }
    public string CustomerID { get; set; }
    public double Freight { get; set; }
    public string ShipCountry { get; set; }
}

private class DropdownOption<T>
{
    public string? Label { get; set; }
    public T? Value { get; set; }
}

The EnterKeyDirection and AllowEditOnKeyPress properties apply only when Mode is set to EditMode.Cell.

Supported events for cell editing

Cell editing in the Blazor Data Grid enables users to update individual cells directly within the Data Grid. Understanding the sequence and purpose of triggered events allows customization and extension of Data Grid functionality. The following table outlines key events associated with cell editing.

Event Description
OnCellEdit Triggers before a cell enters edit mode in the UI, such as on double-click or pressing F2.
OnCellSave Triggers before cell changes are updated in the UI, such as on pressing enter or navigating to another cell.
CellSaved Triggers after cell changes are updated in the UI and the edited values are highlighted in the Data Grid.
EditCanceling Triggered before cancellation of an edit operation. Used for confirmation prompts or rollback logic.
EditCanceled Triggered after cancellation of an edit operation.

Troubleshooting

Issue Likely cause Resolution
Double-clicking a cell does not start editing. AllowEditing is set to false, or Mode is not set to EditMode.Cell. Set both AllowEditing="true" and Mode="EditMode.Cell" in GridEditSettings.
Saved changes appear on the wrong record. The primary key column is missing or IsPrimaryKey is not set. Set IsPrimaryKey="true" on the unique identifier column.
Typing into a selected cell does not start editing. AllowEditOnKeyPress is false (default). Set AllowEditOnKeyPress="true" in GridEditSettings.
Focus does not move after pressing enter key. EnterKeyDirection is set to None. Set EnterKeyDirection to NextRow or NextColumn based on the desired direction.
A cell fails to save. The entered value fails a validation rule on the column. Check the column’s ValidationRules and correct the value, or adjust the rule.

See also