Skip to main content
All docs
V24.2

DxTreeList.CustomizeEditModel Event

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

Namespace: DevExpress.Blazor

Assembly: DevExpress.Blazor.v24.2.dll

NuGet Package: DevExpress.Blazor

Declaration

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

Parameters

Type Description
TreeListCustomizeEditModelEventArgs

An object that contains data for this event.

Remarks

Once a user starts editing a row, the TreeList creates a clone of the edited data item – an edit model. Handle the CustomizeEditModel event to initialize the edit model for new data rows. In the event handler, you can also customize an automatically generated edit model or create a custom edit model.

Read Tutorial: Edit Model Read Tutorial: Edit Data Run Demo: Edit Data

Initialize New Rows

Follow the steps below to initialize an edit model for new data rows:

  1. Handle the CustomizeEditModel event.
  2. Check the IsNew event argument to identify new rows.
  3. Use EditModel and ParentDataItem arguments to link a new node to its parent.
  4. (Optional) Use the EditModel event argument to initialize model fields with predefined values.

The following snippet initializes an edit model for new tasks:

@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            EditModelSaving="TreeList_EditModelSaving"
            DataItemDeleting="TreeList_DataItemDeleting"
            CustomizeEditModel="TreeList_CustomizeEditModel">
    <Columns>
        <DxTreeListCommandColumn />
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
    </Columns>
</DxTreeList>

@code {
    List<EmployeeTask> TreeListData { get; set; }

    protected override void OnInitialized() {
        TreeListData = EmployeeTaskService.GenerateData();
    }
    void TreeList_CustomizeEditModel(TreeListCustomizeEditModelEventArgs e) {
        if(e.IsNew) {
            var newTask = (EmployeeTask)e.EditModel;
            newTask.Id = TreeListData.Max(x => x.Id) + 1;
            newTask.Name = "New task";
            newTask.StartDate = DateTime.Today;
            newTask.DueDate = DateTime.Today.AddDays(7);
            if(e.ParentDataItem != null)
                newTask.ParentId = ((EmployeeTask)e.ParentDataItem).Id;
        }
    }
    async Task TreeList_EditModelSaving(TreeListEditModelSavingEventArgs e) {
        if(e.IsNew)
            TreeListData.Add((EmployeeTask)e.EditModel);
        else
            e.CopyChangesToDataItem();
    }
    async Task TreeList_DataItemDeleting(TreeListDataItemDeletingEventArgs e) {
        TreeListData.Remove((EmployeeTask)e.DataItem);
    }
}

Create a Custom Edit Model

The TreeList component cannot generate an edit model in the following cases:

  • A data item class does not have a parameterless constructor.
  • Data item fields bound to TreeList columns are read-only.
  • In a hierarchical data source, a data type of children nodes differs from the parent node’s data type. In this case, the TreeList cannot determine which data type to use for new rows and generates edit models only for existing rows.

You can create a custom edit model or customize an automatically generated edit model as follows:

  1. Handle the CustomizeEditModel event.
  2. Use the DataItem event argument to access the processed data item. Note that the data item is null for new rows.
  3. Assign your custom edit model to the EditModel event argument.

When you obtain an EditModel object in event handlers or edit templates, cast this object to your custom edit model class as shown below:

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            EditMode="TreeListEditMode.EditForm"
            EditModelSaving="TreeList_EditModelSaving"
            DataItemDeleting="TreeList_DataItemDeleting"
            CustomizeEditModel="TreeList_CustomizeEditModel">
    <Columns>
        <DxTreeListCommandColumn />
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
    </Columns>
    <EditFormTemplate Context="editFormContext">
        @{ 
            var editModel = (EmployeeTaskEditModel)editFormContext.EditModel; 
        }
        @* ... *@
    </EditFormTemplate>
</DxTreeList>

@code {
    List<EmployeeTask> TreeListData { get; set; }

    class EmployeeTaskEditModel {
        public int Id { get; set; }
        public int ParentId { get; set; }
        [Required]
        public string Name { get; set; }
        public string EmployeeName { get; set; }
        public DateTime StartDate { get; set; }
        [Required]
        [Range(typeof(DateTime), "1/12/2016", "1/12/2025", ErrorMessage = "DueDate must be between {1:d} and {2:d}")]
        public DateTime DueDate { get; set; }
    }
    async Task TreeList_EditModelSaving(TreeListEditModelSavingEventArgs e) {
        var editModel = (EmployeeTaskEditModel)e.EditModel;
    }
    void TreeList_CustomizeEditModel(TreeListCustomizeEditModelEventArgs e) {
        if(e.IsNew) {
            var newTask = new EmployeeTaskEditModel { };
            newTask.Id = TreeListData.Max(x => x.Id) + 1;
            newTask.Name = "New task";
            newTask.StartDate = DateTime.Today;
            newTask.DueDate = DateTime.Today.AddDays(7);
            e.EditModel = newTask;
        }
        else {
            var dataItem = (EmployeeTask)e.DataItem;
            e.EditModel = new EmployeeTaskEditModel {
                Id = dataItem.Id,
                ParentId = dataItem.ParentId,
                Name = dataItem.Name,
                EmployeeName = dataItem.EmployeeName,
                StartDate = dataItem.StartDate,
                DueDate = dataItem.DueDate
            };
        }
    }
    // ...
}

Edit Data with Nested Properties

When you edit data, the TreeList 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(TreeListCustomizeEditModelEventArgs 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(TreeListCustomizeEditModelEventArgs 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