New to Telerik UI for ASP.NET Core? Download free 30-day trial


The Grid provides options for visualizing the relations between parent and child records by displaying its table data in a hierarchical manner.

  • To implement hierarchy in the Grid HtmlHelper, use the ClientDetailTemplateId() method and filter the records in the child table based on the parent key field value. For a runnable example, refer to the demo on using hierarchy in the Grid.

  • To implement hierarchy in the Grid TagHelper, use the DetailInit function that initializes the detail Grids by using the Kendo UI Grid for jQuery.

                .Columns(columns =>
                    columns.Bound(e => e.FirstName).Width(130);
                    columns.Bound(e => e.LastName).Width(130);
                    columns.Bound(e => e.Country).Width(130);
                    columns.Bound(e => e.City).Width(110);
                    columns.Bound(e => e.Title);

                .HtmlAttributes(new { style = "height:600px;" })
                .DataSource(dataSource => dataSource
                    .Read(read => read.Action("HierarchyBinding_Employees", "Grid"))

        <script id="template" type="text/kendo-tmpl">
                    .Name("grid_#=EmployeeID#") // template expression, to be evaluated in the master context
                    .Columns(columns =>
                        columns.Bound(o => o.OrderID).Width(110);
                        columns.Bound(o => o.ShipCountry).Width(150);
                        columns.Bound(o => o.ShipAddress).ClientTemplate("\\#= ShipAddress \\#"); // escaped template expression, to be evaluated in the child/detail context
                        columns.Bound(o => o.ShipName).Width(300);
                    .DataSource(dataSource => dataSource
                        .Read(read => read.Action("HierarchyBinding_Orders", "Grid", new { employeeID = "#=EmployeeID#" }))
        <kendo-grid name="grid" height="550" selectable="true" on-detail-init="onDetailInit">
            <datasource type="DataSourceTagHelperType.Custom" custom-type="odata" page-size="20">
                    <read url="" />
            <sortable enabled="true" />
            <pageable button-count="5" refresh="true" page-sizes="new int[] { 5, 10, 20 }">

            <filterable enabled="true" />
                <column field="FirstName" title="First Name" width="240" />
                <column field="LastName" title="Last Name" />
                <column field="Country" title="Country" width="150" />
                <column field="City" title="City" width="150" />

            function onDetailInit(e) {
                    dataSource: {
                        type: "odata",
                        transport: {
                            read: ""
                        serverPaging: true,
                        serverSorting: true,
                        serverFiltering: true,
                        pageSize: 10,
                        filter: { field: "EmployeeID", operator: "eq", value: }
                    scrollable: false,
                    sortable: true,
                    pageable: true,
                    columns: [
                        { field: "OrderID", width: "110px" },
                        { field: "ShipCountry", title: "Ship Country", width: "110px" },
                        { field: "ShipAddress", title: "Ship Address" },
                        { field: "ShipName", title: "Ship Name", width: "300px" }

See Also

In this article