Blazorise DataGrid: Dynamic Data Binding

The Blazorise DataGrid component offers the ability to bind to dynamic data, providing enhanced flexibility for various applications.

Basic Example

To ensure the DataGrid correctly interprets the structure and type of your dynamic data during specific operations, such as creating new items or aggregating data, you need to define a representation within the NewItemCreator function. Below is an illustrative example.
#
First Name
Last Name
Email
City
Zip
Birth Date
Childrens
Gender
Salary
Active
1SamuelCollierSamuel.Collier62@gmail.comNew Lura91848-471426.08.19703M86 030,41 €
2IrvinZiemannIrvin.Ziemann@gmail.comModestomouth16505-840525.05.19743M61 781,31 €
3GeraldPollichGerald82@yahoo.comTheresashire2861229.04.19691M58 810,75 €
4CoraConnCora27@yahoo.comNorth Art10437-225312.02.19845D84 414,66 €
5AlfonsoD'AmoreAlfonso.DAmore@hotmail.comEast Carolefort87912-393306.11.19835F69 318,29 €
Total emails: 25781 793 183,29 €14
1 - 5 of 25 items
25 items
@using System
@using System.Collections.Generic
@using System.ComponentModel.DataAnnotations
@using System.Linq
@using System.Threading.Tasks
@using System.Dynamic

<DataGrid TItem="ExpandoObject"
          Data="inMemoryData"
          Responsive
          ShowPager
          ShowPageSizes
          PageSize="5"
          Editable
          EditMode="DataGridEditMode.Inline"
          NewItemCreator="NewItemCreator">
    <DataGridAggregates>
        <DataGridAggregate Field="Email" Aggregate="DataGridAggregateType.Count">
            <DisplayTemplate>
                @($"Total emails: {context.Value}")
            </DisplayTemplate>
        </DataGridAggregate>
        <DataGridAggregate Field="Salary" Aggregate="DataGridAggregateType.Sum" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "fr-FR" )" />
        <DataGridAggregate Field="IsActive" Aggregate="DataGridAggregateType.TrueCount" />
        <DataGridAggregate Field="Childrens" Aggregate="DataGridAggregateType.Sum" />
    </DataGridAggregates>
    <DataGridColumns>
        <DataGridCommandColumn></DataGridCommandColumn>
        <DataGridColumn Editable TextAlignment="TextAlignment.Center" Field="@nameof( Employee.Id )" Caption="#" Width="Width.Px( 60 )" />
        <DataGridColumn Editable Field="FirstName" Caption="First Name">
        </DataGridColumn>
        <DataGridColumn Editable Field="LastName" Caption="Last Name" />
        <DataGridColumn Editable Field="Email" Caption="Email" />
        <DataGridColumn Editable Field="City" Caption="City">
            <CaptionTemplate>
                <Icon Name="IconName.City" /> @context.Caption
            </CaptionTemplate>
        </DataGridColumn>
        <DataGridColumn Editable Field="Zip" Caption="Zip">
        </DataGridColumn>
        <DataGridDateColumn Field="DateOfBirth" DisplayFormat="{0:dd.MM.yyyy}" Caption="Birth Date" Editable />
        <DataGridNumericColumn Field="Childrens" Caption="Childrens" ReverseSorting="true" Editable Filterable="false" />
        <DataGridSelectColumn Field="Gender" Caption="Gender" Editable Data="EmployeeData.Genders" ValueField="( x ) => ( (Gender)x ).Code" TextField="( x ) => ( (Gender)x ).Description" />
        <DataGridColumn Field="Salary" Caption="Salary" Editable Width="Width.Px( 140 )" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo( "fr-FR" )" TextAlignment="TextAlignment.End">
        </DataGridColumn>
        <DataGridCheckColumn Field="IsActive" Caption="Active" Editable Filterable="false">
            <DisplayTemplate>
                <Check TValue="bool" Value="@(((dynamic)context.Item).IsActive)" Disabled ReadOnly />
            </DisplayTemplate>
        </DataGridCheckColumn>
    </DataGridColumns>
</DataGrid>
@code {

    private readonly EmployeeData EmployeeData = new();

    private List<ExpandoObject> inMemoryData;

    protected override async Task OnInitializedAsync()
    {
        inMemoryData = new();
        var data = ( await EmployeeData.GetDataAsync().ConfigureAwait( false ) ).Take( 25 );

        foreach ( var item in data )
        {

            IDictionary<string, object> expando = new ExpandoObject();

            foreach ( var property in typeof( Employee ).GetProperties() )
            {
                expando.Add( property.Name, property.GetValue( item ) );
            }
            inMemoryData.Add( (ExpandoObject)expando );
        }


        await base.OnInitializedAsync();
    }

    private ExpandoObject NewItemCreator()
    {
        IDictionary<string, object> expando = new ExpandoObject();

        foreach ( var property in typeof( Employee ).GetProperties() )
        {
            expando.Add( property.Name, property.PropertyType.IsValueType ? Activator.CreateInstance( property.PropertyType ) : null );
        }

        return (ExpandoObject)expando;
    }


    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; }
    }
}

Auto Generate Columns Example

The Blazorise DataGrid also supports auto-generating columns based on the data structure. This feature simplifies the process of displaying data by automatically creating columns that match the properties of the bound data objects.

Auto-generated columns support nullable data. If your data includes null values, ensure you provide a NewItemCreator. DataGrid requires an item with non-null values to properly generate the columns.

1 - 5 of 25 items
25 items
@using System
@using System.Collections.Generic
@using System.ComponentModel.DataAnnotations
@using System.Linq
@using System.Threading.Tasks
@using System.Dynamic

<DataGrid TItem="ExpandoObject"
          Data="inMemoryData"
          Responsive
          ShowPager
          ShowPageSizes
          PageSize="5"
          Editable
          EditMode="DataGridEditMode.Inline"
          NewItemCreator="NewItemCreator" />
@code {
    private readonly EmployeeData EmployeeData = new();

    private List<ExpandoObject> inMemoryData;

    protected override async Task OnInitializedAsync()
    {
        inMemoryData = new();
        var data = ( await EmployeeData.GetDataAsync().ConfigureAwait( false ) ).Take( 25 );

        foreach ( var item in data )
        {

            IDictionary<string, object> expando = new ExpandoObject();

            foreach ( var property in typeof( Employee ).GetProperties() )
            {
                expando.Add( property.Name, property.GetValue( item ) );
            }
            inMemoryData.Add( (ExpandoObject)expando );
        }


        await base.OnInitializedAsync();
    }

    private ExpandoObject NewItemCreator()
    {
        IDictionary<string, object> expando = new ExpandoObject();

        foreach ( var property in typeof( Employee ).GetProperties() )
        {
            expando.Add( property.Name,
                property.PropertyType switch
                {
                    { } t when t == typeof( string ) => "",
                    { IsValueType: true } => Activator.CreateInstance( property.PropertyType ) ?? "",
                    _ => "" //better than null
                } );
        }

        return (ExpandoObject)expando;
    }


    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