Blazorise DataGrid: Observable Data

The DataGrid Observable Data feature allows you to bind in memory observable data collections.

Observable Data

By default, DataGrid does not listen to changes in the underlying data collection. This means that if you change the collection, by calling methods like, Add or Remove, the DataGrid will not be updated.

This is in the interest of performance and as such we recommended the following, either:

  • Invoke gridRef.Reload(); when you're done mutating your collection
  • Have your data be observable by using any implementation of the INotifyCollectionChanged, like the ObservableCollection. The example below ilustrates this.

Name
Name 1
Name 2
@using System
@using System.Collections.Generic
@using System.ComponentModel.DataAnnotations
@using System.Linq
@using System.Threading.Tasks
@using System.Collections.ObjectModel;

<Button Clicked="OnAddItemClick" Color="Color.Primary">Add Item</Button>
<Button Clicked="OnRemoveItemClick" Color="Color.Danger">Remove Item</Button>

<DataGrid TItem="Employee"
          Data="@items"
          Responsive>
    <DataGridColumn Field="@nameof( Employee.FirstName )" Caption="Name" Editable="false"></DataGridColumn>
</DataGrid>
@code {
    private ObservableCollection<Employee> items = new() {
        new() { FirstName = "Name 1" },
        new() { FirstName = "Name 2" }
    };

    private Task OnAddItemClick()
    {
        items.Add( new Employee { FirstName = $"Name {items.Count + 1}" } );

        return Task.CompletedTask;
    }

    private Task OnRemoveItemClick()
    {
        if ( items.Count > 0 )
            items.RemoveAt( 0 );

        return Task.CompletedTask;
    }


    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