Blazorise DataGrid: Header Group

Header Group feature for Blazorise DataGrid allows you to easily group a set of defined columns by rendering a top row header which groups the columns by the defined Caption.

Header Group

You can define columns that can be grouped by assigning the HeaderGroupCaption and enabling ShowHeaderGroupCaptions on the DataGrid.

Personal InfoAddress
#
First Name
Email
Last Name
Zip
City
1SamuelSamuel.Collier62@gmail.comCollier91848-4714New Lura
2IrvinIrvin.Ziemann@gmail.comZiemann16505-8405Modestomouth
3GeraldGerald82@yahoo.comPollich28612Theresashire
4CoraCora27@yahoo.comConn10437-2253North Art
5AlfonsoAlfonso.DAmore@hotmail.comD'Amore87912-3933East Carolefort
6JessieJessie_Wilkinson@gmail.comWilkinson34306Mayrafurt
7GregoryGregory63@hotmail.comRenner57895West Marcelleside
8MaryannMaryann.Hilpert12@gmail.comHilpert38859-0368Boehmview
9MerleMerle3@gmail.comPacocha48154-3034North Erlingport
10AngelinaAngelina42@gmail.comWard72291-1146Melyssaview
1 - 10 of 25 items
25 items
@using System
@using System.Collections.Generic
@using System.ComponentModel.DataAnnotations
@using System.Linq
@using System.Threading.Tasks

<DataGrid TItem="Employee"
          Data="inMemoryData"
          ShowPager
          ShowPageSizes
          ShowHeaderGroupCaptions>
    <DataGridColumns>
        <DataGridColumn DisplayOrder=2 TItem="Employee" Field="@nameof( Employee.LastName )" HeaderGroupCaption="Personal Info" Caption="Last Name" />
        <DataGridColumn TextAlignment="TextAlignment.Center" TItem="Employee" Field="@nameof( Employee.Id )" Caption="#" Width="Width.Px( 60 )" />
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.FirstName )" HeaderGroupCaption="Personal Info" Caption="First Name" />
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.Zip )" HeaderGroupCaption="Address" Caption="Zip" />
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.City )" HeaderGroupCaption="Address" Caption="City">
            <CaptionTemplate>
                <Icon Name="IconName.City" /> @context.Caption
            </CaptionTemplate>
        </DataGridColumn>
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.Email )" HeaderGroupCaption="Personal Info" Caption="Email" />
    </DataGridColumns>
</DataGrid>
@code {
    private readonly EmployeeData EmployeeData = new();

    private List<Employee> inMemoryData;

    protected override async Task OnInitializedAsync()
    {
        inMemoryData = ( await EmployeeData.GetDataAsync().ConfigureAwait( false ) ).Take( 25 ).ToList();
        await base.OnInitializedAsync();
    }


    public class Gender
    {
        public string Code { get; set; }
        public string Description { get; set; }
    }

    public class EmployeeData
    {
        private static readonly string[] FirstNames = ["Samuel", "Irvin", "Cora", "Jessie", "Maryann", "Kara"];
        private static readonly string[] LastNames = ["Collier", "Ziemann", "Conn", "Wilkinson", "Hilpert", "Brekke"];
        private static readonly string[] Cities = ["London", "Paris", "New York", "Berlin", "Lisbon", "Zagreb"];

        public static IEnumerable<Gender> Genders =
        [
            new() { Code = null, Description = string.Empty },
            new() { Code = "M", Description = "Male" },
            new() { Code = "F", Description = "Female" },
            new() { Code = "D", Description = "Diverse" }
        ];

        public Task<List<Employee>> GetDataAsync()
            => Task.FromResult( Enumerable.Range( 1, 500 )
                .Select( index =>
                {
                    string firstName = FirstNames[( index - 1 ) % FirstNames.Length];
                    string lastName = LastNames[( index - 1 ) % LastNames.Length];

                    return new Employee
                    {
                        Id = index,
                        FirstName = firstName,
                        LastName = lastName,
                        Email = $"{firstName}.{lastName}{index}@example.com",
                        City = Cities[( index - 1 ) % Cities.Length],
                        Zip = $"{10000 + index}",
                        DateOfBirth = new DateTime( 1950 + index % 50, 1 + index % 12, 1 + index % 28 ),
                        Childrens = index % 6,
                        Gender = index % 3 == 0 ? "D" : index % 2 == 0 ? "F" : "M",
                        Salary = 50000m + index * 137m % 50000m,
                        IsActive = index % 2 == 0,
                        Salaries = Enumerable.Range( 1, index % 4 )
                            .Select( month => new Salary
                            {
                                Date = new DateTime( 2025, month, 1 ),
                                Total = 1000m + index * month * 11m
                            } )
                            .ToList()
                    };
                } )
                .ToList() );
    }

    public class Employee
    {
        public Employee()
        {
        }

        public Employee( Employee other )
        {
            Id = other.Id;
            Childrens = other.Childrens;
            DateOfBirth = other.DateOfBirth;
            City = other.City;
            Email = other.Email;
            FirstName = other.FirstName;
            LastName = other.LastName;
            Gender = other.Gender;
            IsActive = other.IsActive;
            Salaries = other.Salaries;
            Salary = other.Salary;
            Tax = other.Tax;
            Zip = other.Zip;
        }

        [Display( Name = "Id" )]
        public int Id { get; set; }

        [Required]
        public string FirstName { get; set; }

        [Required]
        public string LastName { get; set; }

        [Required]
        [EmailAddress]
        [Display( Name = "Email" )]
        public string Email { get; set; }

        [Display( Name = "City" )]
        public string City { get; set; }

        [Display( Name = "Zip" )]
        public string Zip { get; set; }

        [Display( Name = "DOB" )]
        public DateTime? DateOfBirth { get; set; }

        [Display( Name = "Childrens" )]
        public int? Childrens { get; set; }

        [Display( Name = "Gender" )]
        public string Gender { get; set; }

        [Display( Name = "Salary" )]
        public decimal Salary { get; set; }

        [Display( Name = "Tax" )]
        public decimal Tax
        {
            get
            {
                if ( tax == 0 && Salary > 0 )
                {
                    tax = Salary * TaxPercentage;
                }

                return tax;
            }
            set
            {
                tax = value;
            }
        }

        [Display( Name = "Active" )]
        public bool IsActive { get; set; }

        public List<Salary> Salaries { get; set; } = new();

        public decimal ChildrensPerSalary
            => Salary == 0m
                ? 0m
                : ( Childrens is null || Childrens == 0 ? 1 : Childrens.Value ) / Salary;

        public decimal TaxPercentage = 0.25m;

        private decimal tax;
    }

    public class Salary
    {
        public DateTime Date { get; set; }
        public decimal Total { get; set; }
    }
}

Header Group Template

You can define also further customize the look of each header group by defining HeaderGroupCaptionTemplate.

Personal InformationAddress
#
First Name
Email
Last Name
Zip
City
1SamuelSamuel.Collier62@gmail.comCollier91848-4714New Lura
2IrvinIrvin.Ziemann@gmail.comZiemann16505-8405Modestomouth
3GeraldGerald82@yahoo.comPollich28612Theresashire
4CoraCora27@yahoo.comConn10437-2253North Art
5AlfonsoAlfonso.DAmore@hotmail.comD'Amore87912-3933East Carolefort
6JessieJessie_Wilkinson@gmail.comWilkinson34306Mayrafurt
7GregoryGregory63@hotmail.comRenner57895West Marcelleside
8MaryannMaryann.Hilpert12@gmail.comHilpert38859-0368Boehmview
9MerleMerle3@gmail.comPacocha48154-3034North Erlingport
10AngelinaAngelina42@gmail.comWard72291-1146Melyssaview
1 - 10 of 25 items
25 items
@using System
@using System.Collections.Generic
@using System.ComponentModel.DataAnnotations
@using System.Linq
@using System.Threading.Tasks

<DataGrid TItem="Employee"
          Data="inMemoryData"
          ShowPager
          ShowPageSizes
          ShowHeaderGroupCaptions>
    <DataGridColumns>
        <DataGridColumn DisplayOrder=2 TItem="Employee" Field="@nameof( Employee.LastName )" HeaderGroupCaption="PersonalInfo" Caption="Last Name" />
        <DataGridColumn TextAlignment="TextAlignment.Center" TItem="Employee" Field="@nameof( Employee.Id )" Caption="#" Width="Width.Px( 60 )" />
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.FirstName )" HeaderGroupCaption="PersonalInfo" Caption="First Name" />
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.Zip )" HeaderGroupCaption="Address" Caption="Zip" />
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.City )" HeaderGroupCaption="Address" Caption="City">
            <CaptionTemplate>
                <Icon Name="IconName.City" /> @context.Caption
            </CaptionTemplate>
        </DataGridColumn>
        <DataGridColumn TItem="Employee" Field="@nameof( Employee.Email )" HeaderGroupCaption="PersonalInfo" Caption="Email" />
    </DataGridColumns>
    <HeaderGroupCaptionTemplate>
        @if ( context.HeaderGroupCaption == "PersonalInfo" )
        {
            <Strong TextColor="TextColor.Primary">Personal Information</Strong>
        }
        else if ( context.HeaderGroupCaption == "Address" )
        {
            <Strong TextColor="TextColor.Success">Address</Strong>
        }
    </HeaderGroupCaptionTemplate>
</DataGrid>
@code {
    private readonly EmployeeData EmployeeData = new();

    private List<Employee> inMemoryData;

    protected override async Task OnInitializedAsync()
    {
        inMemoryData = ( await EmployeeData.GetDataAsync().ConfigureAwait( false ) ).Take( 25 ).ToList();
        await base.OnInitializedAsync();
    }


    public class Gender
    {
        public string Code { get; set; }
        public string Description { get; set; }
    }

    public class EmployeeData
    {
        private static readonly string[] FirstNames = ["Samuel", "Irvin", "Cora", "Jessie", "Maryann", "Kara"];
        private static readonly string[] LastNames = ["Collier", "Ziemann", "Conn", "Wilkinson", "Hilpert", "Brekke"];
        private static readonly string[] Cities = ["London", "Paris", "New York", "Berlin", "Lisbon", "Zagreb"];

        public static IEnumerable<Gender> Genders =
        [
            new() { Code = null, Description = string.Empty },
            new() { Code = "M", Description = "Male" },
            new() { Code = "F", Description = "Female" },
            new() { Code = "D", Description = "Diverse" }
        ];

        public Task<List<Employee>> GetDataAsync()
            => Task.FromResult( Enumerable.Range( 1, 500 )
                .Select( index =>
                {
                    string firstName = FirstNames[( index - 1 ) % FirstNames.Length];
                    string lastName = LastNames[( index - 1 ) % LastNames.Length];

                    return new Employee
                    {
                        Id = index,
                        FirstName = firstName,
                        LastName = lastName,
                        Email = $"{firstName}.{lastName}{index}@example.com",
                        City = Cities[( index - 1 ) % Cities.Length],
                        Zip = $"{10000 + index}",
                        DateOfBirth = new DateTime( 1950 + index % 50, 1 + index % 12, 1 + index % 28 ),
                        Childrens = index % 6,
                        Gender = index % 3 == 0 ? "D" : index % 2 == 0 ? "F" : "M",
                        Salary = 50000m + index * 137m % 50000m,
                        IsActive = index % 2 == 0,
                        Salaries = Enumerable.Range( 1, index % 4 )
                            .Select( month => new Salary
                            {
                                Date = new DateTime( 2025, month, 1 ),
                                Total = 1000m + index * month * 11m
                            } )
                            .ToList()
                    };
                } )
                .ToList() );
    }

    public class Employee
    {
        public Employee()
        {
        }

        public Employee( Employee other )
        {
            Id = other.Id;
            Childrens = other.Childrens;
            DateOfBirth = other.DateOfBirth;
            City = other.City;
            Email = other.Email;
            FirstName = other.FirstName;
            LastName = other.LastName;
            Gender = other.Gender;
            IsActive = other.IsActive;
            Salaries = other.Salaries;
            Salary = other.Salary;
            Tax = other.Tax;
            Zip = other.Zip;
        }

        [Display( Name = "Id" )]
        public int Id { get; set; }

        [Required]
        public string FirstName { get; set; }

        [Required]
        public string LastName { get; set; }

        [Required]
        [EmailAddress]
        [Display( Name = "Email" )]
        public string Email { get; set; }

        [Display( Name = "City" )]
        public string City { get; set; }

        [Display( Name = "Zip" )]
        public string Zip { get; set; }

        [Display( Name = "DOB" )]
        public DateTime? DateOfBirth { get; set; }

        [Display( Name = "Childrens" )]
        public int? Childrens { get; set; }

        [Display( Name = "Gender" )]
        public string Gender { get; set; }

        [Display( Name = "Salary" )]
        public decimal Salary { get; set; }

        [Display( Name = "Tax" )]
        public decimal Tax
        {
            get
            {
                if ( tax == 0 && Salary > 0 )
                {
                    tax = Salary * TaxPercentage;
                }

                return tax;
            }
            set
            {
                tax = value;
            }
        }

        [Display( Name = "Active" )]
        public bool IsActive { get; set; }

        public List<Salary> Salaries { get; set; } = new();

        public decimal ChildrensPerSalary
            => Salary == 0m
                ? 0m
                : ( Childrens is null || Childrens == 0 ? 1 : Childrens.Value ) / Salary;

        public decimal TaxPercentage = 0.25m;

        private decimal tax;
    }

    public class Salary
    {
        public DateTime Date { get; set; }
        public decimal Total { get; set; }
    }
}

API

See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.

On this page