Skip to main content

DxGrid.CustomizeEditModel Event

Allows you to create a custom edit model or customize an automatically generated edit model.

Namespace: DevExpress.Blazor

Assembly: DevExpress.Blazor.v23.2.dll

NuGet Package: DevExpress.Blazor

Declaration

[Parameter]
public EventCallback<GridCustomizeEditModelEventArgs> CustomizeEditModel { get; set; }

Parameters

Type Description
GridCustomizeEditModelEventArgs

An object that contains data for this event.

Remarks

Handle the CustomizeEditModel event to implement a custom edit model or customize an automatically generated edit model.

Read Tutorial: Edit Data Run Demo: Edit Data View Example: Create and edit unbound columns

Create a Custom Edit Model

The Grid cannot generate an edit model in the following cases:

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

Follow the steps below to implement a custom edit model.

  1. Declare an edit model class and its fields.
  2. Handle the CustomizeEditModel event.
  3. Use the event argument’s DataItem property to access a data item. If this property is set to null, the edit model corresponds to a new row.
  4. Assign your custom edit model to the event argument’s EditModel property.
  5. In the EditModelSaving event handler and the EditFormTemplate, cast the EditModel property value to your custom edit model class.
@using Microsoft.EntityFrameworkCore
@inject IDbContextFactory<NorthwindContext> NorthwindContextFactory
@implements IDisposable
@using System.ComponentModel.DataAnnotations;

<DxGrid Data="GridDataSource"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        CustomizeEditModel="Grid_CustomizeEditModel">
    <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<object> GridDataSource { get; set; }
    NorthwindContext Northwind { get; set; }

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

    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;
        // 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();
        }
    }

    void 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
            };
        }
    }

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

Initialize New Rows

The CustomizeEditModel event allows you to display predefined values in data editors when a user adds a new row.

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

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

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

<DxGrid Data="GridDataSource"
        EditModelSaving="OnEditModelSaving"
        DataItemDeleting="OnDataItemDeleting"
        KeyFieldName="EmployeeId"
        CustomizeEditModel="Grid_CustomizeEditModel">
    <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<object> GridDataSource { get; set; }
    NorthwindContext Northwind { get; set; }

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

    void Grid_CustomizeEditModel(GridCustomizeEditModelEventArgs e) {
        if (e.IsNew) {
            var editModel = (Employee)e.EditModel;
            editModel.HireDate = DateTime.Today;
        }
    }

    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();
    }
}

Edit Data with Nested Properties

When you edit data, the Grid clones a bound data item – namely creates an object of the same type and copies all property values into it. If a property is of a reference type, the reference is copied but the referred object is not copied. As the result, the original object and its clone refer to the same object.

To edit nested objects, create a copy of these objects manually (make a deep copy of the original data item object). You can use the following approaches to implement a deep copy operation:

  • Handle the CustomizeEditModel event, clone the nested object, and assign it to field whose value is the reference type.

    void OnCustomizeEditModel(GridCustomizeEditModelEventArgs obj) {
        var customer = (Customer)obj.EditModel;
        customer.Address = customer.Address?.Clone() ?? new Address();
    }
    
    public class Person {
        public int ID { get; set; }
        public string FirstName {get; set;}
        public string LastName { get; set; }
        public Address Address { get; set; }
    }
    public class Address {
        public string StreetLine1 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public int ZipCode { get; set; }
        public Address Clone() {
            return (Address) MemberwiseClone();
        }
    }
    
  • Create constructors for the data item type and the nested object’s type. In the data item type constructor, the nested object type constructor clones the nested object with its property values. Handle the CustomizeEditModel event and call a data item’s class constructor to initialize the edit model.

    void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e) {
        e.EditModel = new Person((Person)e.DataItem);
    }
    
    public Person(Person person) {
        this.ID = person.ID;
        this.FirstName = person.FirstName;
        this.LastName = person.LastName;
        this.Address = new Address(person.Address); 
    }
    public Address(Address address) {
        this.StreetLine1 = address.StreetLine1;
        this.City = address.City;
        this.State = address.State;
        this.ZipCode = address.ZipCode;
    }
    
See Also