New to Telerik UI for Blazor? Download free 30-day trial

Grid Grouping

The Grid component offers support for grouping.

Basics

To enable grouping, set the grid's Groupable property to true.

Drag a column header to the group panel and the grid will create groups in the data rows based on the available values for that field. An indicator will be shown for the column that is used for grouping. The group header shows the value for the field by which it is grouping.

You can also group by multiple fields and groups for subsequent fields will be nested within their parent groups. When adding a group, you can drag it in the desired position in the list of current groups.

To remove a group setting, click the [x] button on its indicator in the group panel.

To prevent grouping by a field, set Groupable="false" on its column. This can be useful for fields with unique values like IDs or names.

You can also use aggregates for the grouped data.

Enable grouping in Telerik Grid

Drag the column header of the "Team" and/or "On Vacation" column to the group panel at the top

<TelerikGrid Data=@GridData Groupable="true" Pageable="true" Height="400px">
    <GridColumns>
        <GridColumn Field=@nameof(Employee.Name) Groupable="false" />
        <GridColumn Field=@nameof(Employee.Team) Title="Team" />
        <GridColumn Field=@nameof(Employee.IsOnLeave) Title="On Vacation" />
    </GridColumns>
</TelerikGrid>

@code {
    public List<Employee> GridData { get; set; }

    protected override void OnInitialized()
    {
        GridData = new List<Employee>();
        var rand = new Random();
        for (int i = 0; i < 15; i++)
        {
            GridData.Add(new Employee()
            {
                EmployeeId = i,
                Name = "Employee " + i.ToString(),
                Team = "Team " + i % 3,
                IsOnLeave = i % 2 == 0
            });
        }
    }

    public class Employee
    {
        public int EmployeeId { get; set; }
        public string Name { get; set; }
        public string Team { get; set; }
        public bool IsOnLeave { get; set; }
    }
}

How grouping works in the Telerik grid

Blazor Grid Grouping Overview

Aggregates

The grid lets you define and use aggregates that it can calculate for you. You can read more about using them in the Aggregates article.

Load On Demand

The grid can load the grouped data on demand only. This can be useful if you have many groups and you want the user to first scroll through them without having to load all their data at once. Instead, the child items for a group can be loaded only when the user expands the group. This mode can also be used with Virtual Scrolling. You can read more about this feature in the Grid - Load Group Data On Demand article.

Group From Code

You can group the Grid from your code through the Grid state. This is possible even if Groupable="false" and the group panel is not visible. You can define the list of fields by which the grid is grouped and indexes of groups that will be collapsed (all groups are expanded by default).

If you want to set an initial state to the Grid, use a similar snippet, but in the OnStateInit event

Set grouping programmatically

@using Telerik.DataSource

<TelerikGrid @ref="@GridRef"
             Data="@GridData"
             Pageable="true"
             Groupable="true">
    <GridToolBarTemplate>
        <TelerikButton ThemeColor="@ThemeConstants.Button.ThemeColor.Success"
                       OnClick="@( () => SetGridGroups(false) )">Group Grid by Team</TelerikButton>
        <TelerikButton ThemeColor="@ThemeConstants.Button.ThemeColor.Primary"
                       OnClick="@( () => SetGridGroups(true) )">Group Grid by Team and IsOnLeave</TelerikButton>
        <span class="k-separator"></span>
        <TelerikButton OnClick="@RemoveGridGroups">Remove All Groups</TelerikButton>
    </GridToolBarTemplate>
    <GridColumns>
        <GridColumn Field="@(nameof(Employee.Name))" Title="Employee Name" />
        <GridColumn Field="@(nameof(Employee.Team))" />
        <GridColumn Field="@(nameof(Employee.HireDate))" Title="Hire Date" DisplayFormat="{0:d}" />
        <GridColumn Field="@(nameof(Employee.IsOnLeave))" Title="Is On Leave" />
    </GridColumns>
</TelerikGrid>

@code {
    private TelerikGrid<Employee>? GridRef { get; set; }

    private List<Employee> GridData { get; set; } = new();

    private async Task SetGridGroups(bool shouldGroupBySecondColumn)
    {
        if (GridRef != null)
        {
            var gridState = GridRef.GetState();

            // Remove any existing Grid groups
            // You can also modify or reorder existing GroupDescriptors.
            gridState.GroupDescriptors.Clear();

            gridState.GroupDescriptors.Add(new GroupDescriptor()
            {
                Member = nameof(Employee.Team),
                MemberType = typeof(string),
                // https://feedback.telerik.com/blazor/1544196-allow-sorting-the-grouped-column
                SortDirection = ListSortDirection.Ascending
            });

            if (shouldGroupBySecondColumn)
            {
                gridState.GroupDescriptors.Add(new GroupDescriptor()
                {
                    Member = nameof(Employee.IsOnLeave),
                    MemberType = typeof(bool),
                    // https://feedback.telerik.com/blazor/1544196-allow-sorting-the-grouped-column
                    SortDirection = ListSortDirection.Descending
                });
            }

            await GridRef.SetStateAsync(gridState);
        }
    }

    private async Task RemoveGridGroups()
    {
        if (GridRef != null)
        {
            var gridState = GridRef.GetState();

            gridState.GroupDescriptors.Clear();

            await GridRef.SetStateAsync(gridState);
        }
    }

    protected override void OnInitialized()
    {
        for (int i = 1; i <= 30; i++)
        {
            GridData.Add(new Employee()
            {
                Id = i,
                Name = $"Name {i}",
                Team = $"Team {i % 5 + 1}",
                HireDate = DateTime.Today.AddDays(-Random.Shared.Next(1, 3000)),
                IsOnLeave = i % 4 == 0 ? true : false
            });
        }
    }

    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string Team { get; set; } = string.Empty;
        public DateTime HireDate { get; set; }
        public bool IsOnLeave { get; set; }
    }
}

More Examples

The following articles and sample projects can be helpful when implementing grouping:

  • Capture Group event - the grid state lets you know when it changes so you can capture different aspects of the change

  • Server Grouping - this article explains how to implement manual data source operations so you can offload the work to the server. It provides the overview of how to setup the grid for that, and examples - several with local data and links a repository with examples using REST API endpoints.

  • Static group that is always present

See Also

In this article