Back to Devexpress

Selection and Focus in Blazor TreeList

blazor-405082-components-treelist-selection.md

latest63.6 KB
Original Source

Selection and Focus in Blazor TreeList

  • Jul 07, 2025
  • 33 minutes to read

Focused Row vs. Selection

Focused and selected rows have a lot in common. For example, you can allow users to focus a row and display/update additional information outside of the TreeList component. You can do the same with selected rows - whether you allow single or multiple selection. The key differences between the two features are outlined below:

  • The focused row is a navigation feature, while selected rows facilitate operations on data rows. For example, if you navigate to a different page or filter the TreeList, focus can change. Row selection doesn’t change as a result of navigation or data shaping operations.
  • Focused row appearance usually has more contrast compared to selected rows.

Selection in Blazor TreeList

The DevExpress Blazor TreeList supports single and multiple (default) row selection. Users can click rows or use a specially-designed column to select/deselect records. You can also manage selection in code.

Note

The TreeList component uses the key field’s values to identify and compare data items. If your data object has a primary key, assign it to the KeyFieldName property. Otherwise, the TreeList uses standard .NET value equality comparison to identify data items.

Run Demo: Multiple Row Selection

Single Row Selection

Set the SelectionMode property to Single to allow users to select only one row at a time:

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            SelectionMode="TreeListSelectionMode.Single"
            AllowSelectRowByClick="true">
    <Columns>
        <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();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

Tip

Use the row focus feature to navigate between TreeList records and perform actions related to the currently focused row.

Select Rows in the UI

The TreeList component allows users to select rows in the following ways:

Row Click

Set the AllowSelectRowByClick property to true to allow users to select rows by mouse clicks, tap gestures, and keyboard shortcuts. Note that the selection state of a parent node does not affect selection states of its child nodes and vice versa.

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            AllowSelectRowByClick="true"
            @bind-SelectedDataItems="@SelectedDataItems">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
    </Columns>
</DxTreeList>

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

    protected override void OnInitialized() {
        TreeListData = EmployeeTaskService.GenerateData();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

The following user operations are available:

OperationDescription
ClickClick a row to select it and clear the selection of all other rows.
Ctrl+ClickHold down the Ctrl key and click a row to add/remove the row to/from selection.
Shift+ClickClick the first row in a range, hold down the Shift key, and click the last row in the range to select a range of rows.
Ctrl+Shift+ClickHold down the Ctrl key, click the first row in the range, hold down the Shift key, and click the last row in the range to add the range of rows to the selection.
SpaceFocus a cell in a row and press Space to select the row and clear the selection of all other rows.
TapTap a row to select it and clear the selection of all other rows.
Long TapTap a row for an extended period of time to add/remove the row to/from selection.
Long Tap+MoveTap a row for an extended period and move the finger to add a range of rows to the current selection.

Selection Column

Declare a DxTreeListSelectionColumn object in the Columns template to display the selection column.

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId">
    <Columns>
        <DxTreeListSelectionColumn />
        <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();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

When the SelectionMode property is set to Multiple (the default value), the selection column displays checkboxes. Users can click them to select and deselect individual rows. Note that the selection state of a parent node does not affect selection states of its child nodes and vice versa.

In Multiple selection mode, the selection column displays the Select All checkbox in the column header. A user can click this checkbox to select or deselect rows on the current page or on all TreeList pages depending on the SelectAllCheckboxMode property value. Available property values are as follows:

PageThe Select All checkbox does not affect child rows of collapsed items and selects/deselects rows on the current page only.AllPagesThe Select All checkbox affects child rows of collapsed items and selects/deselects all rows on all pages.MixedThe Select All checkbox does not affect child rows of collapsed items and selects/deselects rows on the current page only. An additional drop-down button displays a context menu that allows users to select and deselect all rows on all pages.

razor
<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            SelectAllCheckboxMode="TreeListSelectAllCheckboxMode.Mixed">
    <Columns> 
        @* ... *@ 
    </Columns>
</DxTreeList>

To hide the Select All checkbox, disable the column’s AllowSelectAll option.

Note

The Select All checkbox functionality has limitations in certain operation modes. To learn more, see the following section: Limitations.

When the SelectionMode property is set to Single, the selection column displays radio buttons. Users can click a button to select one row at a time.

razor
<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            SelectionMode="TreeListSelectionMode.Single">
    <Columns>
        <DxTreeListSelectionColumn />
        @* ... *@ 
    </Columns>
</DxTreeList>

You can use the FixedPosition property to freeze the selection column and keep it visible on screen while users scroll the TreeList horizontally.

Select and Deselect Rows in Code

TreeList implements a number of Select * and Deselect * methods that allow you to change row selection in code. The table below lists these methods.

|

Select* Methods

|

Deselect* Methods

|

Description

| | --- | --- | --- | |

SelectRow

|

DeselectRow

|

Set the selection state of a row with the specified visible index.

| |

SelectRows

|

DeselectRows

|

Set the selection state of rows with the specified visible indexes.

| |

SelectDataItem

|

DeselectDataItem

|

Set selection state of a row that corresponds to the specified data item.

| |

SelectDataItems

|

DeselectDataItems

|

Set selection state of rows that correspond to the specified data items.

| |

SelectAllOnPage

|

DeselectAllOnPage

|

Set the selection state of rows on the current visible page.
These methods do not affect child rows of collapsed items.

| |

SelectAllAsync

|

DeselectAllAsync

|

Set the selection state of all rows in the TreeList.
These methods do not affect the selection state of rows hidden by a filter.

|

Call the ClearSelection() method to clear selection of all rows on all pages, including rows hidden by a filter.

Obtain Selected Data Items

Single Selection Mode

Implement two-way binding for the SelectedDataItem property to access the data item that corresponds to the selected row. When a property value changes, the SelectedDataItemChanged event fires.

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            AllowSelectRowByClick="true"
            SelectionMode="TreeListSelectionMode.Single"
            @bind-SelectedDataItem="@SelectedDataItem">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
    </Columns>
</DxTreeList>

<div>
    <p><b>Selected task:</b> @((SelectedDataItem as EmployeeTask)?.Name ?? "(none)")</p>
</div>

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

    protected override void OnInitialized() {
        TreeListData = EmployeeTaskService.GenerateData();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

Multiple Selection Mode

Implement two-way binding for the SelectedDataItems property to access data items that correspond to selected rows. When a property value changes, the SelectedDataItemsChanged event fires.

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            AllowSelectRowByClick="true"
            @bind-SelectedDataItems="@SelectedDataItems">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
    </Columns>
</DxTreeList>

<div>
    <b>Selected tasks:</b>
    @{
        if(SelectedDataItems != null)
            foreach (var task in SelectedDataItems.Cast<EmployeeTask>()) {    
                <li>@task.Name</li>
            }
    }
</div>

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

    protected override void OnInitialized() {
        TreeListData = EmployeeTaskService.GenerateData();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

The SelectedDataItemsChanged event allows you to get data items that are added to and removed from selection. For this purpose, cast the event handler’s parameter to the ITreeListSelectionChanges interface. The SelectedDataItems and DeselectedDataItems properties return information about selection changes.

razor
<DxTreeList Data="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            AllowSelectRowByClick="true"
            SelectedDataItems="@SelectedDataItems"
            SelectedDataItemsChanged="OnSelectedDataItemsChanged">
    <Columns>
        @* ...*@
    </Columns>
</DxTreeList>

@code {
    List<EmployeeTask> TreeListData { get; set; }
    IReadOnlyList<object> SelectedDataItems { get; set; }
    string SelectedItemsInfo { get; set; }
    string DeselectedItemsInfo { get; set; }

    void OnSelectedDataItemsChanged(IReadOnlyList<object> newSelection) {
        if (newSelection is ITreeListSelectionChanges changes) {
            SelectedItemsInfo = string.Join("; ", changes.SelectedDataItems.Cast<EmployeeTask>().Select(p => p.Name));
            DeselectedItemsInfo = string.Join("; ", changes.DeselectedDataItems.Cast<EmployeeTask>().Select(p => p.Name));
        }
        SelectedDataItems = newSelection;
    }
}

Selection Limitations

When the TreeList component is in virtual scrolling mode:

  • The Page mode automatically switches to AllPages mode.
  • The TreeList component cannot determine the state of the Select All checkbox in Mixed mode. In such cases, the TreeList sets the checkbox state to indeterminate and displays the checkbox in read-only mode.

When the TreeList component is bound to a GridDevExtremeDataSource or loads data on demand:

  • Sort and filter operations cancel incomplete “select all” and “deselect all” processes.

  • The second call to SelectAllAsync or DeselectAllAsync method cancels the operation initiated by the previously called method.

  • SelectAllAsync and DeselectAllAsync methods load all data to the TreeList and can reduce overall performance and increase memory consumption.

  • If the SelectAllCheckboxMode property is set to AllPages, the TreeList component switches it to Mixed to improve performance.

  • In virtual scrolling mode, the TreeList component sets the SelectAllCheckboxMode property to Mixed, sets the Select All checkbox state to indeterminate, and displays the checkbox in read-only mode.

Focused Row

Set the FocusedRowEnabled property to true to allow users to focus individual TreeList rows. The focused row is always visible on the current TreeList page. If you change the current page, the focused row changes.

Run Demo: Focused Row

You can handle the FocusedRowChanged event to react to a focused row change. In the following code snippet, the TreeList component displays additional information about the focused space object:

razor
@inject SpaceObjectDataProvider SpaceObjectDataProvider

<DxTreeList Data="TreeListData"
            ChildrenFieldName="Satellites"
            FocusedRowEnabled="true"
            FocusedRowChanged="TreeList_FocusedRowChanged">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" />
        <DxTreeListDataColumn FieldName="TypeOfObject" Caption="Type" />
        <DxTreeListDataColumn FieldName="Mass10pow21kg" Caption="Mass, kg" DisplayFormat="N2">
            <HeaderCaptionTemplate>Mass, 10<sup>21</sup> &#215; kg</HeaderCaptionTemplate>
        </DxTreeListDataColumn>
        <DxTreeListDataColumn FieldName="MeanRadiusInKM" Caption="Radius, km" DisplayFormat="N2" />
        <DxTreeListDataColumn FieldName="Volume10pow9KM3" DisplayFormat="N2">
            <HeaderCaptionTemplate>Volume, 10<sup>9</sup> &#215; km<sup>3</sup></HeaderCaptionTemplate>
        </DxTreeListDataColumn>
        <DxTreeListDataColumn FieldName="SurfaceGravity" DisplayFormat="N2">
            <HeaderCaptionTemplate>Gravity, m/s<sup>2</sup></HeaderCaptionTemplate>
        </DxTreeListDataColumn>
    </Columns>
</DxTreeList>

@if (FocusedSpaceObject != null) {
    <h5>@FocusedSpaceObject.Name</h5>
    <ul>
        <li><b>Radius</b>: @FocusedSpaceObject.MeanRadiusInKM.ToString("N2") km</li>
        <li><b>Density</b>: @FocusedSpaceObject.Density.ToString("N2") g/cm<sup>3</sup></li>
        <li><b>Gravity</b>: @FocusedSpaceObject.SurfaceGravity.ToString("N2") m/s<sup>2</sup></li>
    </ul>
}

@code {
    object TreeListData { get; set; }
    SpaceObject FocusedSpaceObject { get; set; }

    protected override async Task OnInitializedAsync() {
        TreeListData = SpaceObjectDataProvider.GenerateData();
    }
    void TreeList_FocusedRowChanged(TreeListFocusedRowChangedEventArgs e) {
        FocusedSpaceObject = e.DataItem as SpaceObject;
    }
}
csharp
using System.Collections.Generic;

public class SpaceObject {
    public string Name { get; set; }
    public double MeanRadiusInKM { get; set; }
    public double Volume10pow9KM3 { get; set; }
    public double Mass10pow21kg { get; set; }
    public double Density { get; set; }
    public double SurfaceGravity { get; set; }
    public string TypeOfObject { get; set; }
    public List<SpaceObject> Satellites { get; set; }
    public SpaceObject(
        string name,
        double meanRadiusInKM,
        double volume10pow9KM3,
        double mass10pow21kg,
        double density,
        double surfaceGravity,
        string typeOfObject,
        List<SpaceObject> satellites = null
    ) {
        Name = name;
        MeanRadiusInKM = meanRadiusInKM;
        Volume10pow9KM3 = volume10pow9KM3;
        Mass10pow21kg = mass10pow21kg;
        Density = density;
        SurfaceGravity = surfaceGravity;
        TypeOfObject = typeOfObject;
        Satellites = satellites ?? new List<SpaceObject>();
    }
}
csharp
public class SpaceObjectDataProvider {
    public List<SpaceObject> GenerateData() {
        return new List<SpaceObject>() {
            new SpaceObject("Sun", 696000, 1412000000, 1989100000, 1.409, 274.0, "Star", new List<SpaceObject>() {
                new SpaceObject("Mercury", 2439.7, 60.83, 330.2, 5.43, 3.7, "Planet"),
                new SpaceObject("Venus", 6051.8, 928.43, 4868.5, 5.24, 8.872, "Planet"),
                new SpaceObject("Earth", 6371.0, 1083.21, 5973.6, 5.515, 9.78033, "Planet", new List<SpaceObject> () {
                    new SpaceObject("Moon", 1737.1, 21.958, 73.5, 3.3464, 1.625, "Satellite")
                }),
                new SpaceObject("Mars", 3390.0, 163.18, 641.85, 3.94, 3.7, "Planet"),
                new SpaceObject("Jupiter", 69911, 1431280, 1898600, 1.33, 24.79, "Planet", new List<SpaceObject>() {
                    new SpaceObject("Ganymede", 2631.2, 76.30, 148.2, 1.936, 1.428, "Satellite"),
                    new SpaceObject("Callisto", 2410.3, 58.65, 107.6, 1.83, 1.23603, "Satellite"),
                    new SpaceObject("Io", 1821.5, 25.32, 89.3, 3.528, 1.797, "Satellite"),
                    new SpaceObject("Europa", 1561, 15.93, 48, 3.01, 1.316, "Satellite"),
                }),
                new SpaceObject("Saturn", 58232, 827130, 568460, 0.70, 10.445, "Planet", new List<SpaceObject>() {
                    new SpaceObject("Titan", 2576, 71.52, 134.5, 1.88, 1.354, "Satellite"),
                    new SpaceObject("Rhea", 764.4, 1.87, 2.3166, 1.23, 0.26, "Satellite"),
                    new SpaceObject("Iapetus", 736, 1.55, 1.9739, 1.08, 0.223, "Satellite"),
                    new SpaceObject("Dione", 561.6, 0.73, 1.096, 1.48, 0.232, "Satellite"),
                    new SpaceObject("Tethys", 533, 0.624, 0.6173, 1.15, 0.145, "Satellite"),
                    new SpaceObject("Enceladus", 252.1, 0.067, 0.108, 1.61, 0.111, "Satellite"),
                    new SpaceObject("Mimas", 198.3, 0.033, 0.03749, 1.15, 0.06363, "Satellite")
                }),
                new SpaceObject("Uranus", 25362, 68340, 86832, 1.30, 8.87, "Planet", new List<SpaceObject>() {
                    new SpaceObject("Titania", 788.9, 2.06, 3.526, 1.72, 0.378, "Satellite"),
                    new SpaceObject("Oberon", 761.4, 1.85, 3.014, 1.63, 0.347, "Satellite"),
                    new SpaceObject("Umbriel", 584.7, 0.84, 1.2, 1.4, 0.234, "Satellite"),
                    new SpaceObject("Ariel", 578.9, 0.81, 1.35, 1.67, 0.269, "Satellite"),
                    new SpaceObject("Miranda", 235.8, 0.055, 0.0659, 1.20, 0.07910375, "Satellite"),
                }),
                new SpaceObject("Neptune", 24622, 62540, 102430, 1.76, 11.15, "Planet", new List<SpaceObject>() {
                    new SpaceObject("Triton", 1353.4, 10.38, 21.5, 2.061, 0.782, "Satellite"),
                    new SpaceObject("Proteus", 210, 0.038, 0.050, 1.3, 0.0666, "Satellite"),
                }),
                new SpaceObject("Eris", 1170, 7, 16.7, 2.25, 0.662, "Dwarf planet"),
                new SpaceObject("Pluto", 1153, 7.15, 13.105, 2.0, 0.61, "Dwarf planet"),
                new SpaceObject("Makemake", 710, 1.8, 3, 2.0, 0.4, "Dwarf planet"),
                new SpaceObject("Haumea", 575, 1.3, 4.006, 3, 0.44, "Dwarf planet"),
                new SpaceObject("Ceres", 475, 0.437, 0.95, 2.08, 0.27, "Dwarf planet"),
                new SpaceObject("Pallas", 266, 0.078, 0.211, 2.8, 0.2, "Asteroid"),
                new SpaceObject("Vesta", 264.6, 0.078, 0.262, 3.42, 0.251, "Asteroid")
            })
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<SpaceObjectDataProvider>();

This section contains comprehensive selection and focus-related API references.

Show Selection API References

TreeList API memberTypeDescription
AllowSelectRowByClickPropertySpecifies whether users can select and deselect rows by mouse clicks, tap gestures, and keyboard shortcuts.
SelectAllCheckboxModePropertySpecifies whether the Select All checkbox selects all rows on the current page or on all TreeList pages.
SelectionModePropertySpecifies the selection mode.
SelectedDataItemPropertyIn single selection mode, this property specifies the data item that corresponds to the selected TreeList row.
SelectedDataItemsPropertyIn multiple selection mode, this property specifies data items that correspond to selected TreeList rows.
ExportSelectedRowsOnlyPropertySpecifies whether the TreeList exports selected rows only.
IsDataItemSelected(Object)MethodReturns whether the row that corresponds to the specified data item is selected.
IsRowSelected(Int32)MethodReturns whether the specified row is selected.
ClearSelection()MethodClears selection.
DeselectAllAsync()MethodDeselects all rows in the TreeList.
DeselectAllOnPage()MethodDeselects all rows on the currently visible page except for child rows of collapsed items.
DeselectDataItem(Object)MethodDeselects a row that corresponds to the specified data item.
DeselectDataItems(IEnumerable<Object>)MethodDeselects rows that correspond to the specified data items.
DeselectRow(Int32)MethodDeselects a row with the specified visible index.
DeselectRows(IEnumerable<Int32>)MethodDeselects rows with the specified visible indexes.
SelectAllAsync(Boolean)MethodSelects or deselects all rows in the TreeList.
SelectAllOnPage(Boolean)MethodSelects or deselects all rows on the currently visible page except for child rows of collapsed items.
SelectDataItem(Object, Boolean)MethodSelects or deselects a row that corresponds to the specified data item.
SelectDataItems(IEnumerable<Object>, Boolean)MethodSelects or deselects rows that correspond to the specified data items.
SelectRow(Int32, Boolean)MethodSelects or deselects a row with the specified visible index.
SelectRows(IEnumerable<Int32>, Boolean)MethodSelects or deselects rows with the specified visible indexes.
SelectedDataItemChangedEventIn single selection mode, fires when a TreeList row is selected.
SelectedDataItemsChangedEventIn multiple selection mode, fires when the selection in the TreeList changes.
Selection Column API memberTypeDescription
AllowSelectAllPropertySpecifies whether the selection column contains the Select All checkbox.
CellDisplayTemplatePropertySpecifies a template for selection column cells.
FilterRowCellTemplatePropertySpecifies a template for the selection column’s filter row cell.
HeaderTemplatePropertySpecifies a template for the selection column header.

Show Focus API References

TreeList API memberTypeDescription
FocusedRowEnabledPropertySpecifies whether row focus is enabled.
GetFocusedDataItem()MethodReturns a data item bound to the focused data row.
GetFocusedRowIndex()MethodReturns the visible index of the focused row.
IsDataItemFocused(Object)MethodReturns whether the row bound to the specified data item is focused.
IsRowFocused(Int32)MethodReturns whether the row with the specified visible index is focused.
SetFocusedRowIndex(Int32)MethodMoves focus to the row with the specified visible index.
FocusedRowChangedEventFires when row focus changes.

Task-Based Examples

This section contains code samples that demonstrate row selection functionality.

Limit the Number of Selected Rows

The SelectedDataItemsChanged event fires when the selection in the TreeList changes. Handle this event to determine the number of selected rows and deselect them if the number of selected rows exceeds a predefined maximum value.

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList @ref=TreeList
            Data ="TreeListData"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            SelectedDataItems="SelectedItems"
            SelectedDataItemsChanged="TreeList_SelectedDataItemsChanged">
    <Columns>
        <DxTreeListSelectionColumn />
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
    </Columns>
</DxTreeList>

@code {
    ITreeList TreeList;
    int maxSelectedRowCount = 3;
    IReadOnlyList<object> SelectedItems;
    List<EmployeeTask> TreeListData { get; set; }

    void TreeList_SelectedDataItemsChanged(IReadOnlyList<object> newSelection) {
        if (newSelection?.Count > maxSelectedRowCount)
            SelectedItems = newSelection.Skip(newSelection.Count - maxSelectedRowCount).ToList().AsReadOnly();
        else
            SelectedItems = newSelection;
    }

    protected override void OnInitialized() {
        TreeListData = EmployeeTaskService.GenerateData();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

“Select All” Checkbox: Respond to State Changes

No predefined event fires when the Select All checkbox changes its state. You can create your own template to reproduce the default render and observe the checkbox’s state.

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData" KeyFieldName="Id" ParentKeyFieldName="ParentId">
    <Columns>
        <DxTreeListSelectionColumn>
            <HeaderTemplate>
                <DxCheckBox T="bool?"
                            Checked="context.Selected"
                            CheckedChanged="(newValue) => SelectAllCheckboxClicked(newValue, context)" />
            </HeaderTemplate>
        </DxTreeListSelectionColumn>
        <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 SelectAllCheckboxClicked(bool? newValue, TreeListSelectionColumnHeaderTemplateContext context) {
        context.Selected = newValue!.Value;
        // Your actions here
    }
}

Suppress Row Selection When a Certain Element in TreeList is Clicked

When the AllowSelectRowByClick property is set to true, users can click rows to select them. If your TreeList contains links or custom buttons, a click on the element initiates the element-related action, then the RowClick event fires and the row is selected. Use the stopPropagation directive attribute to prevent the click from triggering TreeList events. In this case, clicking these links or buttons does not cause row selection.

razor
<DxTreeListDataColumn FieldName="WikiPage" AllowSort="false" Width="150px">
    <CellDisplayTemplate>
        <a @onclick:stopPropagation href="@context.Value">Open Wikipedia</a>
        @* or *@
        <div @onclick:stopPropagation="true">
            @* Custom buttons *@
        </div>
    </CellDisplayTemplate>
</DxTreeListDataColumn>

Use Custom Checkboxes Inside a Selection Column

To replace selection column editors with custom checkboxes, place the DxCheckBox<T> component in CellDisplayTemplate and implement two-way binding to bind the Checked checkbox property to the context.Selected value.

razor
<DxTreeListSelectionColumn Width="104px">
    <CellDisplayTemplate Context="SelContext">
        <DxCheckBox @bind-Checked="SelContext.Selected" />
    </CellDisplayTemplate>
</DxTreeListSelectionColumn>