DataGrid: Binding Data
Basic Example
<DataGrid TItem="Employee" Data="" @bind-SelectedRow="" Responsive> <DataGridCommandColumn /> <DataGridColumn Field="@nameof(Employee.Id)" Caption="#" Sortable="false" /> <DataGridColumn Field="@nameof(Employee.FirstName)" Caption="First Name" Editable /> <DataGridColumn Field="@nameof(Employee.LastName)" Caption="Last Name" Editable /> <DataGridColumn Field="@nameof(Employee.Email)" Caption="Email" Editable /> <DataGridColumn Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable> <EditTemplate> <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" /> </EditTemplate> </DataGridColumn> </DataGrid>
@code{ [Inject] public EmployeeData EmployeeData { get; set; } private List<Employee> employeeList; private Employee selectedEmployee; protected override async Task OnInitializedAsync() { employeeList = await EmployeeData.GetDataAsync(); await base.OnInitializedAsync(); } }
Large Data
By default, DataGrid
will load everything in memory and it will perform the necessary operations like paging, sorting and filtering. For large datasets this is impractical and so for these scenarios it is advised to load data page-by-page.
This is accomplished with the use of ReadData
event handler and TotalItems
attribute. When you define the usage of ReadData
the DataGrid
will automatically switch to manual mode and every interaction with the grid will be proxied through the ReadData
. This means that you as a developer will be responsible for all the loading, filtering and sorting of the data.
ReadData
event handler used to handle the loading of dataTotalItems
total number of items in the source data-set
Bellow you can find a basic example of how to load large data and apply it to the DataGrid
.
Just as in the previous example everything is the same except that now we must define the attribute ReadData
and TotalItems
. They’re used to handle all of the loading, filtering and sorting of an actual data.
<DataGrid TItem="Employee" Data="" ReadData="" TotalItems="" PageSize="1" ShowPager Responsive> <DataGridCommandColumn /> <DataGridColumn Field="@nameof(Employee.Id)" Caption="#" Sortable="false" /> <DataGridColumn Field="@nameof(Employee.FirstName)" Caption="First Name" Editable /> <DataGridColumn Field="@nameof(Employee.LastName)" Caption="Last Name" Editable /> <DataGridColumn Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable> <EditTemplate> <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" /> </EditTemplate> </DataGridColumn> </DataGrid>
@code{ [Inject] public EmployeeData EmployeeData { get; set; } private List<Employee> employeeList; protected override async Task OnInitializedAsync() { employeeList = await EmployeeData.GetDataAsync(); await base.OnInitializedAsync(); } private int totalEmployees; private async Task OnReadData( DataGridReadDataEventArgs<Employee> e ) { if ( !e.CancellationToken.IsCancellationRequested ) { List<Employee> response = null; // this can be call to anything, in this case we're calling a fictional api //var response = await Http.GetJsonAsync<Employee[]>( $"some-api/employees?page={e.Page}&pageSize={e.PageSize}" ); if ( e.ReadDataMode is DataGridReadDataMode.Virtualize ) response = (await EmployeeData.GetDataAsync()).Skip( e.VirtualizeOffset ).Take( e.VirtualizeCount ).ToList(); else if ( e.ReadDataMode is DataGridReadDataMode.Paging ) response = (await EmployeeData.GetDataAsync()).Skip( ( e.Page - 1 ) * e.PageSize ).Take( e.PageSize ).ToList(); else throw new Exception( "Unhandled ReadDataMode" ); if ( !e.CancellationToken.IsCancellationRequested ) { totalEmployees = (await EmployeeData.GetDataAsync()).Count; employeeList = new List<Employee>( response ); // an actual data for the current page } } } }
Virtualization
By settingVirtualize
, you will enable virtualize capabilities on the DataGrid
, meaning that instead of having pagination, you’ll be able to scroll across the data with perceived improved performance.
Virtualization is a technique for limiting UI rendering to just the parts that are currently visible. For example, virtualization is helpful when the app must render a long list of items and only a subset of items is required to be visible at any given time.
You will still have access to every available DataGrid
feature. VirtualizeOptions
allows to further customize the Virtualize
feature.
TaskCanceledException
on the background, this does not seem to crash your application.
TaskCanceledException when scrolling Virtualized component #28280<DataGrid TItem="Employee" Data="" @bind-SelectedRow="" Responsive Virtualize VirtualizeOptions="@(new() { DataGridHeight = "250px"})"> <DataGridCommandColumn /> <DataGridColumn Field="@nameof(Employee.Id)" Caption="#" Sortable="false" /> <DataGridColumn Field="@nameof(Employee.FirstName)" Caption="First Name" Editable /> <DataGridColumn Field="@nameof(Employee.LastName)" Caption="Last Name" Editable /> <DataGridColumn Field="@nameof(Employee.Email)" Caption="Email" Editable /> <DataGridColumn Field="@nameof(Employee.Salary)" Caption="Salary" DisplayFormat="{0:C}" DisplayFormatProvider="@System.Globalization.CultureInfo.GetCultureInfo("fr-FR")" Editable> <EditTemplate> <NumericEdit TValue="decimal" Value="@((decimal)context.CellValue)" ValueChanged="@( v => context.CellValue = v)" /> </EditTemplate> </DataGridColumn> </DataGrid>
@code { [Inject] public EmployeeData EmployeeData { get; set; } private List<Employee> employeeList; private Employee selectedEmployee; protected override async Task OnInitializedAsync() { employeeList = await EmployeeData.GetDataAsync(); await base.OnInitializedAsync(); } }