Skip to main content
A newer version of this page is available. .

Edit Data and Validate Input

  • 22 minutes to read

Users can employ an inline edit row or invoke a standard or pop-up edit form to edit data in the Grid. The EditMode property specifies the current edit mode.

This topic describes how to enable data editing, validate user input, and customize edit-related options.

Blazor Grid Editing

Run Demo: Edit Forms Watch Video: Grid - Edit Data

Enable Editing

Follow the steps below to allow users to add, edit, and delete data rows.

1. Show UI Elements

Declare a DxGridCommandColumn object in the Columns template. This column displays the predefined New, Edit, and Delete command buttons. To hide unnecessary buttons, disable the NewButtonVisible, EditButtonVisible, and/or DeleteButtonVisible options.

<DxGrid Data="Data"
        ...>
    <Columns>
        <DxGridCommandColumn />
        @*...*@
    </Columns>
</DxGrid>

Blazor Grid Command Column

Once a user clicks the New or Edit button, the edit row or form appears. When the user clicks the Delete button, the delete confirmation dialog is shown.

You can define the command column’s CellDisplayTemplate and HeaderTemplate to implement custom command elements. You can also create external command elements outside the Grid. Handle click events of these elements and call the following methods:

StartEditNewRowAsync
Displays the edit row or form used to create a new data row.
StartEditRowAsync | StartEditDataItemAsync
Display the edit row or form used to modify the specified row or data item.
ShowRowDeleteConfirmation | ShowDataItemDeleteConfirmation
Display the delete confirmation dialog for the specified row or data item.

View Example: Use icons instead of default command buttons View Example: Disable row editing depending on row values

2. Define an Edit Row or Edit Form Template

In EditForm and PopupEditForm modes, use the EditFormTemplate to define the edit form content. The default edit form shows only the predefined Save and Cancel buttons. You can disable the EditFormButtonsVisible option to hide the predefined Save and Cancel buttons and implement your own buttons. Note the following specifics:

In EditRow mode, specify a common DataColumnCellEditTemplate or individual CellEditTemplate for each column to define an edit row’s content. The edit row displays the Save and Cancel buttons in the command column. To hide these buttons, use the SaveButtonVisible and CancelButtonVisible properties.

The Grid creates an edit model based on a bound data item. You can also create a custom edit model. Use the template’s context parameter to access the EditModel and DataItem. In the template, place data editors and implement two-way binding between editor values and edit model fields. An edit model field updates every time a user changes the corresponding editor value.

Note

If you place a templated component in the edit form or row, ensure that you specify the Context parameter explicitly either for the Grid or for the component used in the edit form or row. Otherwise, an error occurs.

The following snippet uses the DxFormLayout component to create an edit form that displays DevExpress editors for all visible data columns:

<DxGrid Data="Data"
        ...>
    <Columns>
        <DxGridCommandColumn />
        @*...*@
    </Columns>
    <EditFormTemplate Context="editFormContext">
        @{
            var employee = (Employee)editFormContext.EditModel;
        }
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                <DxTextBox @bind-Text="@employee.FirstName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                <DxTextBox @bind-Text="@employee.LastName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                <DxTextBox @bind-Text="@employee.Title" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                <DxDateEdit @bind-Date="@employee.HireDate" />
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
</DxGrid>

Blazor Grid Edit Form Content

View Example: How to edit a row on a separate page

3. Save Changes and Reload Data

Handle the events listed below to process changes.

EditModelSaving

This event fires when a user submits the edit form or saves changes in the edit row, and validation is passed. Handle this event to check user input and access permissions and post changes to an underlying data source.

Use the event argument’s EditModel property to access the edit model that stores all changes. The DataItem property returns the data item. The IsNew property identifies whether the edit model corresponds to a new or existing row.

Once the event handler is executed, the edit form or row is closed. If you do not save changes to the data source and want to keep the edit form or row open, set the event argument’s Cancel property to true.

DataItemDeleting

This event fires when a user confirms the delete operation in the delete confirmation dialog. Handle this event to check user access permissions and delete a data item from an underlying data source.

The event argument’s DataItem property returns the data item that should be removed.

If the data item is currently selected in the Grid and you do not remove this item from the data source, set the Cancel property to true to keep the data item selected.

Grid data should be reloaded after you post updates to the data source in the EditModelSaving or DataItemDeleting event handler. The following scenarios are possible:

Change a Data Instance
Change an instance of a field/property bound to the Data parameter if you post updates to the underlying service (such as a DbContext EF Core). The Grid reloads its data in response to this change. The example below demonstrates this scenario.
Keep a Data Instance

Do not change a field/property instance bound to the Data parameter in the following cases:

The Grid refreshes its data after the event handler is executed.

Reload Manually
You can call the Grid’s Reload() method in the event handler to reload data manually. In this case, set the Reload event argument to false to prevent unnecessary repeated reload.

The following example saves changes to an underlying DbContext EF Core object:

<DxGrid Data="Data"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId">
        @* ... *@
</DxGrid>

@code {
    IEnumerable<object> Data { get; set; }
    NorthwindContext Northwind { get; set; }
    @* ... *@
    async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
        var editModel = (Employee)e.EditModel;
        // Re-query a data item from the database.
        var dataItem = e.IsNew ? new Employee() : Northwind.Employees.Find(editModel.EmployeeId);
        // Assign changes from the edit model to the data item.
        if (dataItem != null) {
            dataItem.FirstName = editModel.FirstName;
            dataItem.LastName = editModel.LastName;
            dataItem.Title = editModel.Title;
            dataItem.HireDate = editModel.HireDate;
            // Post changes to the database.
            if (e.IsNew)
                await Northwind.AddAsync(dataItem);
            await Northwind.SaveChangesAsync();
            // Reload the entire Grid.
            Data = await Northwind.Employees.ToListAsync();
        }
    }

    async Task OnDataItemDeleting(GridDataItemDeletingEventArgs e) {
        // Re-query a data item from the database.
        var dataItem = Northwind.Employees.Find((e.DataItem as Employee).EmployeeId);
        if (dataItem != null) {
            // Remove the data item from the database.
            Northwind.Remove(dataItem);
            await Northwind.SaveChangesAsync();
            // Reload the entire Grid.
            Data = await Northwind.Employees.ToListAsync();
        }
    }
    @* ... *@
}

View Example: How to post changes to an in-memory data source

4. Specify a Key Field

The Grid compares and identifies data items to ensure correct edit and delete operations. If your data object has a primary key, assign it to the KeyFieldName or KeyFieldNames property. Otherwise, the Grid uses the standard .NET value equality comparison to identify data items.

<DxGrid Data="Data"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId">
        @* ... *@
</DxGrid>

Complete Code

View Example: Bind the Grid to data with Entity Framework Core

@page "/"
@using Microsoft.EntityFrameworkCore
@using BindToData.Models
@inject IDbContextFactory<NorthwindContext> NorthwindContextFactory
@implements IDisposable

<DxGrid Data="Data"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId">
    <Columns>
        <DxGridCommandColumn />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        @{
            var employee = (Employee)editFormContext.EditModel;
        }
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                <DxTextBox @bind-Text="@employee.FirstName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                <DxTextBox @bind-Text="@employee.LastName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                <DxTextBox @bind-Text="@employee.Title" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                <DxDateEdit @bind-Date="@employee.HireDate" />
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
</DxGrid>

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

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

    async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
        var editModel = (Employee)e.EditModel;
        // Re-query a data item from the database.
        var dataItem = e.IsNew ? new Employee() : Northwind.Employees.Find(editModel.EmployeeId);
        // Assign changes from the edit model to the data item.
        if (dataItem != null) {
            dataItem.FirstName = editModel.FirstName;
            dataItem.LastName = editModel.LastName;
            dataItem.Title = editModel.Title;
            dataItem.HireDate = editModel.HireDate;
            // Post changes to the database.
            if (e.IsNew)
                await Northwind.AddAsync(dataItem);
            await Northwind.SaveChangesAsync();
            // Reload the entire Grid.
            Data = await Northwind.Employees.ToListAsync();
        }
    }

    async Task OnDataItemDeleting(GridDataItemDeletingEventArgs e) {
        // Re-query a data item from the database.
        var dataItem = Northwind.Employees.Find((e.DataItem as Employee).EmployeeId);
        if (dataItem != null) {
            // Remove the data item from the database.
            Northwind.Remove(dataItem);
            await Northwind.SaveChangesAsync();
            // Reload the entire Grid.
            Data = await Northwind.Employees.ToListAsync();
        }
    }

    public void Dispose() {
        Northwind?.Dispose();
    }
}

Edit Modes

Use the EditMode property to choose one of the following edit modes:

GridEditMode.EditForm (Default)

The Grid displays the edit form instead of the edited data row.

Blazor Grid Edit Form

Run Demo: Edit Forms Run Demo: Input Validation

GridEditMode.PopupEditForm

The Grid displays the edit form in a pop-up window.

You can use the PopupEditFormCssClass property to assign a CSS class. The PopupEditFormHeaderText property allows you to change text in the edit form header.

Blazor Grid Popup Edit Form

The code below activates PopupEditForm mode.

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

<DxGrid Data="GridDataSource"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        EditMode="GridEditMode.PopupEditForm">
    <Columns>
        <DxGridCommandColumn />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        @{
            var employee = (Employee)editFormContext.EditModel;
        }
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                <DxTextBox @bind-Text="@employee.FirstName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                <DxTextBox @bind-Text="@employee.LastName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                <DxTextBox @bind-Text="@employee.Title" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                <DxDateEdit @bind-Date="@employee.HireDate" />
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
</DxGrid>

@code {
    IEnumerable<object> GridDataSource { get; set; }
    NorthwindContext Northwind { get; set; }

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

    async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
        var editModel = (Employee)e.EditModel;
        // Re-query a data item from the database.
        var dataItem = e.IsNew ? new Employee() : Northwind.Employees.Find(editModel.EmployeeId);

        // Assign changes from the edit model to the data item.
        if (dataItem != null) {
            dataItem.FirstName = editModel.FirstName;
            dataItem.LastName = editModel.LastName;
            dataItem.Title = editModel.Title;
            dataItem.HireDate = editModel.HireDate;
            // Post changes to the database.
            if (e.IsNew)
                await Northwind.AddAsync(dataItem);
            await Northwind.SaveChangesAsync();
            // Reload the entire Grid.
            GridDataSource = await Northwind.Employees.ToListAsync();
        }
    }

    async Task OnDataItemDeleting(GridDataItemDeletingEventArgs e) {
        // Re-query a data item from the database.
        var dataItem = Northwind.Employees.Find((e.DataItem as Employee).EmployeeId);
        if (dataItem != null) {
            // Remove the data item from the database.
            Northwind.Remove(dataItem);
            await Northwind.SaveChangesAsync();
            // Reload the entire Grid.
            GridDataSource = await Northwind.Employees.ToListAsync();
        }
    }

    public void Dispose() {
        Northwind?.Dispose();
    }
}

Run Demo: Edit Forms Run Demo: Input Validation

GridEditMode.EditRow

The Grid displays inline editors instead of the edited row. Specify a common DataColumnCellEditTemplate or individual CellEditTemplate for each column to define an edit row’s content.

Blazor Grid Inline Edit Row

The code below activates EditRow mode.

    @inject NwindDataService NwindDataService

    <DxGrid @ref="Grid"
            Data="DataSource"
            PageSize="12"
            KeyFieldName="EmployeeId"
            ValidationEnabled="false"
            CustomizeEditModel="Grid_CustomizeEditModel"
            EditModelSaving="Grid_EditModelSaving"
            DataItemDeleting="Grid_DataItemDeleting"
            EditMode="GridEditMode.EditRow"
            EditorRenderMode="GridEditorRenderMode.Integrated"
            SizeMode="Params.SizeMode">
        <Columns>
            <DxGridCommandColumn Width="160px" />
            <DxGridDataColumn FieldName="FirstName" MinWidth="80">
                <CellEditTemplate>
                    @{
                        var employee = (EditableEmployee)context.EditModel;
                    }
                    <DxTextBox @bind-Text="@employee.FirstName"></DxTextBox>
                </CellEditTemplate>
            </DxGridDataColumn>
            <DxGridDataColumn FieldName="LastName" MinWidth="80">
                <CellEditTemplate>
                    @{
                        var employee = (EditableEmployee)context.EditModel;
                    }
                    <DxTextBox @bind-Text="@employee.LastName"></DxTextBox>
                </CellEditTemplate>
            </DxGridDataColumn>
            <DxGridDataColumn FieldName="Title" MinWidth="100">
                <CellEditTemplate>
                    @{
                        var employee = (EditableEmployee)context.EditModel;
                    }
                    <DxTextBox @bind-Text="@employee.Title"></DxTextBox>
                </CellEditTemplate>
            </DxGridDataColumn>
            <DxGridDataColumn FieldName="HireDate" Width="10%" MinWidth="80">
                <CellEditTemplate>
                    @{
                        var employee = (EditableEmployee)context.EditModel;
                    }
                    <DxDateEdit @bind-Date="@employee.HireDate"></DxDateEdit>
                </CellEditTemplate>
            </DxGridDataColumn>
        </Columns>
    </DxGrid>

@code {
    IEnumerable<EditableEmployee> DataSource { get; set; }
    IGrid Grid { get; set; }

    protected override async Task OnInitializedAsync() {
        DataSource = await NwindDataService.GetEmployeesEditableAsync();
    }
    protected override async Task OnAfterRenderAsync(bool firstRender) {
        if(firstRender)
            await Grid.StartEditRowAsync(0);
    }
    void Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e) {
        if(e.IsNew) {
            var newEmployee = (EditableEmployee)e.EditModel;
            newEmployee.FirstName = "John";
            newEmployee.LastName = "Doe";
        }
    }
    async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e) {
        if(e.IsNew)
            await NwindDataService.InsertEmployeeAsync((EditableEmployee)e.EditModel);
        else
            await NwindDataService.UpdateEmployeeAsync((EditableEmployee)e.DataItem, (EditableEmployee)e.EditModel);
        await UpdateDataAsync();
    }
    async Task Grid_DataItemDeleting(GridDataItemDeletingEventArgs e) {
        await NwindDataService.RemoveEmployeeAsync((EditableEmployee)e.DataItem);
        await UpdateDataAsync();
    }
    async Task UpdateDataAsync() {
        DataSource = await NwindDataService.GetEmployeesEditableAsync();
    }
}

Run Demo: Edit Row Run Demo: Input Validation

View Example: Grid - Inline Editing and Cell Edit Templates

Validate User Input

The Grid allows you to validate input data and display errors.

Important

You should not rely on grid input validation alone to secure your Blazor-powered app. Grid validation is designed to improve usability. A threat actor can bypass validation and send malicious data to the server. To minimize security related threats/risks, you must validate user input using multiple strategies. Refer to the following topic for more information: Validate User Input.

Built-In Validation

The Grid uses the DataAnnotationsValidator to validate user input based on data annotation attributes defined in an edit model.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
// ...
    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<System.DateTime> 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<System.DateTime> HireDate { get; set; }
        // ...
    }

When you define the EditFormTemplate or CellEditTemplate, you can use any of the following techniques to display validation messages:

  • Use Blazor’s standard ValidationMessage component to display messages for individual data editors.
  • Use the template context’s EditContext property to access validation messages and display them manually.

    View Example: Grid - Inline Editing and Cell Edit Templates

  • Use the ValidationSummary component to summarize validation messages.

    Run Demo: Input Validation

    <DxGrid ...>
        <Columns>
            @* ... *@
        </Columns>
        <EditFormTemplate Context="editFormContext">
            @{
                var employee = (Employee)editFormContext.EditModel;
            }
            <DxFormLayout>
                <DxFormLayoutItem Caption="First Name:">
                    <DxTextBox @bind-Text="@employee.FirstName" />
                </DxFormLayoutItem>
                <DxFormLayoutItem Caption="Last Name:">
                    <DxTextBox @bind-Text="@employee.LastName" />
                </DxFormLayoutItem>
                <DxFormLayoutItem Caption="Title:">
                    <DxTextBox @bind-Text="@employee.Title" />
                </DxFormLayoutItem>
                <DxFormLayoutItem Caption="Hire Date:">
                    <DxDateEdit @bind-Date="@employee.HireDate" />
                </DxFormLayoutItem>
                <DxFormLayoutItem ColSpanMd="12">
                    <ValidationSummary />
                </DxFormLayoutItem>
            </DxFormLayout>
        </EditFormTemplate>
    </DxGrid>
    

Once a user removes focus from data editors or attempts to submit the edit form or save changes in the edit row, the editors become marked with colored outlines: green indicates valid values, red – invalid values.

Blazor Grid Input Validation

Custom Validation

You can create custom validator components as described in the following Microsoft topic: Validator components.

To enable custom validation in the Grid, declare validator components in one of the following templates:

CustomValidators
In this case, declared validators override the standard DataAnnotationsValidator. If you need to use DataAnnotationsValidator in addition to custom validators, declare it in the CustomValidators template explicitly.
EditFormTemplate or CellEditTemplate
In this case, the Grid uses the standard DataAnnotationsValidator and the declared custom validators. Do not place the DataAnnotationsValidator in the edit form template to avoid duplicated validation messages.

The following example uses the custom validator to check the Title field value.

View Example: Custom Validation

@page "/"

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

<DxGrid Data="GridDataSource"
        EditModelSaving="OnEditModelSaving"
        KeyFieldName="EmployeeId">
    <Columns>
        <DxGridCommandColumn DeleteButtonVisible="false" />
        <DxGridDataColumn FieldName="FirstName" />
        <DxGridDataColumn FieldName="LastName" />
        <DxGridDataColumn FieldName="Title" />
        <DxGridDataColumn FieldName="HireDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        @{
            var employee = (Employee)editFormContext.EditModel;
        }
        <DxFormLayout>
            <DxFormLayoutItem Caption="First Name:">
                <DxTextBox @bind-Text="@employee.FirstName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Last Name:">
                <DxTextBox @bind-Text="@employee.LastName" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Title:">
                <DxTextBox @bind-Text="@employee.Title" />
            </DxFormLayoutItem>
            <DxFormLayoutItem Caption="Hire Date:">
                <DxDateEdit @bind-Date="@employee.HireDate" />
            </DxFormLayoutItem>
            <DxFormLayoutItem ColSpanMd="12">
                <ValidationSummary />
            </DxFormLayoutItem>
        </DxFormLayout>
    </EditFormTemplate>
    <CustomValidators>
        <MyCustomValidator DataItemValidating="ValidateGridData" />
    </CustomValidators>
</DxGrid>

@code {
    IEnumerable<object> GridDataSource { get; set; }
    NorthwindContext Northwind { get; set; }

    void ValidateGridData(ValidationMessageStoreEventArgs e) {
        var employee = (Employee)e.EditModel;
        if (employee.Title == null || !employee.Title.Contains("Sales")) {
            e.AddError(nameof(employee.Title), "The Title field value should contain 'Sales'.");
        }
    }

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

    async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
        var editModel = (Employee)e.EditModel;
        var dataItem = e.IsNew ? new Employee() : Northwind.Employees.Find(editModel.EmployeeId);
        if (dataItem != null) {
            dataItem.FirstName = editModel.FirstName;
            dataItem.LastName = editModel.LastName;
            dataItem.Title = editModel.Title;
            dataItem.HireDate = editModel.HireDate;
            if (e.IsNew)
                await Northwind.AddAsync(dataItem);
            await Northwind.SaveChangesAsync();
            GridDataSource = await Northwind.Employees.ToListAsync();
        }
    }

    public void Dispose() {
        Northwind?.Dispose();
    }
}

Blazor Grid Editing Custom Validation

Disable Validation

Set the ValidationEnabled option to false to disable input validation in DevExpress data editors located in the edit form or row.

<DxGrid Data="Data"
        ...
        ValidationEnabled="false">
    @* ... *@
</DxGrid>

Initialize New Rows

You can display predefined values in data editors when a user adds a new row.

  1. Handle the CustomizeEditModel event.
  2. Check the event argument’s IsNew property to identify new rows.
  3. Use the EditModel to access the edit model and initialize model field values.

The following snippet specifies the predefined value for the HireDate field:

<DxGrid Data="GridDataSource"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        CustomizeEditModel="Grid_CustomizeEditModel">
        @* ... *@
</DxGrid>

@code {
    IEnumerable<object> GridDataSource { get; set; }
    @* ... *@
    async Task Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e) {
        if (e.IsNew) {
            var editModel = (Employee)e.EditModel;
            editModel.HireDate = DateTime.Today;
        }
    }
    @* ... *@
}

Create a Custom Edit Model

The Grid creates an edit model based on a bound data item, but the Grid cannot do this in the following cases:

  • A data item class does not have a parameterless constructor.
  • Data item fields bound to Grid columns are read-only.

Handle the CustomizeEditModel event to create a custom edit model or customize an automatically-generated edit model. Use the event argument’s DataItem property to access a data item. Assign your custom edit model to the event argument’s EditModel property.

In the EditModelSaving event handler and the EditFormTemplate, cast the EditModel property value to your custom edit model class.

<DxGrid Data="GridDataSource"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        CustomizeEditModel="Grid_CustomizeEditModel">
    <Columns>
    @* ... *@
    </Columns>
    <EditFormTemplate Context="editFormContext">
        @{
            var employee = (EmployeeEditModel)editFormContext.EditModel;
        }
        @* ... *@
    </EditFormTemplate>
</DxGrid>

@code {
    IEnumerable<object> GridDataSource { get; set; }
    @* ... *@
    class EmployeeEditModel {
        public int? EmployeeId { get; set; }
        [Required, MaxLength(64)]
        public string LastName { get; set; }
        [Required, MaxLength(64)]
        public string FirstName { get; set; }
        public string Title { get; set; }
        public DateTime? HireDate { get; set; }
    }

    async Task OnEditModelSaving(GridEditModelSavingEventArgs e) {
        var editModel = (EmployeeEditModel)e.EditModel;
        @* ... *@
    }
    @* ... *@
    async Task Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e) {
        var dataItem = (Employee)e.DataItem;
        if (dataItem == null)
            e.EditModel = new EmployeeEditModel { };
        else {
            e.EditModel = new EmployeeEditModel {
                EmployeeId = dataItem.EmployeeId,
                FirstName = dataItem.FirstName,
                LastName = dataItem.LastName,
                Title = dataItem.Title,
                HireDate = dataItem.HireDate
            };
        }
    }
    @* ... *@
}

Respond to Edit Start and Cancel

Handle the following events to create a custom response to edit start and cancel actions:

EditStart
Fires before the edit form or row appears.
EditCanceling
Fires when the edit row or form closes and discards changes.