Back to Devexpress

Pop-Up and Inline Edit Forms in Blazor Grid

blazor-404757-components-grid-editing-and-validation-edit-modes-edit-forms.md

latest19.3 KB
Original Source

Pop-Up and Inline Edit Forms in Blazor Grid

  • Mar 20, 2026
  • 8 minutes to read

In EditForm or PopupEditForm mode, the Grid displays an inline or pop-up edit form instead of the edited data row. Users can click command buttons to create, modify, and delete grid rows.

Run Demo: Edit Forms

Video

YouTube video

Enable Editing

The built-in edit form shows only the predefined Save and Cancel buttons. Use the EditFormTemplate to populate the edit form with editors. Call the GetEditor(String) method to add an automatically generated column editor in the edit form.

Note

When you place a templated component in the edit form template, a Razor error may occur. To prevent this error, specify the Context parameter explicitly either for the Grid template or for the nested component.

Once you define the edit form content, follow the steps below to enable data editing:

  1. Declare a DxGridCommandColumn object in the Columns template to display the command column.

  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). Set the EditMode property to PopupEditForm to display the edit form in a pop-up window.

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

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

<DxGrid Data="Data"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        CustomizeEditModel="OnCustomizeEditModel"
        KeyFieldName="EmployeeId">
    <Columns>
        <DxGridCommandColumn />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                @editFormContext.GetEditor("FirstName")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                @editFormContext.GetEditor("LastName")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                @editFormContext.GetEditor("Title")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                @editFormContext.GetEditor("HireDate")
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
</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);
});

Customize Pop-Up Edit Form

You can set the EditMode property to PopupEditForm to display the edit form in a pop-up window. Specify the PopupEditFormCssClass property to apply a CSS class to the pop-up edit form. The PopupEditFormHeaderText property allows you to change text in the edit form header.

The following code snippet changes the pop-up edit form’s size and header text:

razor
<DxGrid Data="Data"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        EditMode="GridEditMode.PopupEditForm"
        PopupEditFormHeaderText="Edit Employee"
        PopupEditFormCssClass="my-style">
    <Columns>
        <DxGridCommandColumn />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                @editFormContext.GetEditor("FirstName")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                @editFormContext.GetEditor("LastName")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                @editFormContext.GetEditor("Title")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                @editFormContext.GetEditor("HireDate")
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
</DxGrid>
css
.my-style {
    min-width: 800px;
}

Hide Predefined Edit Form Buttons

Disable the EditFormButtonsVisible option to hide the predefined Save and Cancel buttons. Instead of them, you can implement your own buttons. Note the following specifics:

  • Instead of the Save button, you can use a submit button or a button that calls the SaveChangesAsync method on click.

  • To discard changes and hide the edit form, call the CancelEditAsync method in a custom button’s click event handler.

The following example displays custom Save and Cancel buttons in the edit form:

razor
<DxGrid Data="Data"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        EditFormButtonsVisible="false">
    <Columns>
        <DxGridCommandColumn />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                @editFormContext.GetEditor("FirstName")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                @editFormContext.GetEditor("LastName")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                @editFormContext.GetEditor("Title")
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                @editFormContext.GetEditor("HireDate")
            </DxFormLayoutItem>
            <DxFormLayoutItem ColSpanMd="12">
                <DxButton SubmitFormOnClick="true" Text="Save" />
                <DxButton Click="@(() => MyGrid.CancelEditAsync())" Text="Cancel" />
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
</DxGrid>

View Example: Use an External Popup as an Edit Form

This section contains a comprehensive editing-related API reference.

Show API Reference

DxGrid API memberTypeDescription
CustomValidatorsPropertyAllows you to declare custom validator components.
EditFormButtonsVisiblePropertySpecifies whether the edit form contains the predefined Save and Cancel buttons.
EditFormTemplatePropertySpecifies the template used to display the edit form.
EditModePropertySpecifies how users edit Grid data.
EditNewRowPositionPropertySpecifies the position of UI elements used to create new rows.
PopupEditFormCssClassPropertyAssigns a CSS class to the pop-up edit form.
PopupEditFormHeaderTextPropertySpecifies text displayed in the pop-up edit form’s header.
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
CellDisplayTemplatePropertySpecifies a template used to display command column cells.
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.
DxGridDataColumn API memberTypeDescription
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.