Use the Kendo Grid when displaying structured tabular data. Requires general Blazor setup (TelerikRootComponent, AddTelerikBlazor, theme). See skills-blazor.md for setup.
Common use cases:
- Admin dashboards
- CRUD management tables
- Financial or reporting tables
- Large datasets requiring sorting, filtering, or paging
<TelerikGrid TItem="Product"
Data="@Products"
Pageable="true"
PageSize="10"
Sortable="true"
Filterable="true"
Height="400px">
<GridColumns>
<GridColumn Field="@nameof(Product.ProductID)" Title="ID" />
<GridColumn Field="@nameof(Product.ProductName)" Title="Product Name" />
<GridColumn Field="@nameof(Product.UnitPrice)" Title="Price" DisplayFormat="{0:C}" />
<GridColumn Field="@nameof(Product.Discontinued)" Title="Active">
<Template>
<input type="checkbox" checked="@context.Discontinued" disabled />
</Template>
</GridColumn>
</GridColumns>
</TelerikGrid>
@code {
private List<Product> Products { get; set; }
}<TelerikGrid TItem="Product"
OnRead="@OnReadProducts"
Pageable="true"
PageSize="10"
Sortable="true"
Filterable="true"
Height="400px">
<GridColumns>
<GridColumn Field="@nameof(Product.ProductID)" Title="ID" />
<GridColumn Field="@nameof(Product.ProductName)" Title="Product Name" />
<GridColumn Field="@nameof(Product.UnitPrice)" Title="Price" DisplayFormat="{0:C}" />
</GridColumns>
</TelerikGrid>
@code {
private async Task OnReadProducts(GridReadEventArgs args)
{
var result = await ProductService.GetProductsAsync(
args.Request.Page,
args.Request.PageSize,
args.Request.Sorts,
args.Request.Filters);
args.Data = result.Data;
args.Total = result.Total;
}
}<TelerikGrid TItem="Product"
Data="@Products"
EditMode="@GridEditMode.Popup"
OnCreate="@OnCreate"
OnUpdate="@OnUpdate"
OnDelete="@OnDelete"
ConfirmDelete="true"
Pageable="true"
PageSize="10"
Height="400px">
<GridToolBar>
<GridCommandButton Command="Add">Add Product</GridCommandButton>
</GridToolBar>
<GridColumns>
<GridCommandColumn>
<GridCommandButton Command="Edit">Edit</GridCommandButton>
<GridCommandButton Command="Delete">Delete</GridCommandButton>
</GridCommandColumn>
<GridColumn Field="@nameof(Product.ProductName)" Title="Name" />
<GridColumn Field="@nameof(Product.UnitPrice)" Title="Price" DisplayFormat="{0:C}" />
<GridColumn Field="@nameof(Product.CategoryId)" Title="Category">
<EditorTemplate>
<TelerikDropDownList TItem="Category"
TValue="int"
Data="@Categories"
TextField="Name"
ValueField="Id"
@bind-Value="@context.CategoryId" />
</EditorTemplate>
</GridColumn>
</GridColumns>
</TelerikGrid>
@code {
private List<Product> Products { get; set; }
private List<Category> Categories { get; set; }
private void OnCreate(GridCommandEventArgs args)
{
Products.Add((Product)args.Item);
}
private void OnUpdate(GridCommandEventArgs args)
{
var updated = (Product)args.Item;
var existing = Products.First(x => x.ProductID == updated.ProductID);
// Apply changes to existing
}
private void OnDelete(GridCommandEventArgs args)
{
var item = (Product)args.Item;
Products.Remove(Products.First(x => x.ProductID == item.ProductID));
}
}<TelerikDropDownList TItem="Category"
TValue="int?"
Data="@Categories"
TextField="Name"
ValueField="Id"
DefaultText="All categories"
@bind-Value="@SelectedCategoryId"
ValueChange="@OnCategoryChange" />
<TelerikGrid @ref="@GridRef"
TItem="Product"
OnRead="@OnReadProducts"
Pageable="true"
PageSize="10"
Sortable="true"
Height="400px">
<GridColumns>
<GridColumn Field="@nameof(Product.ProductName)" Title="Name" />
<GridColumn Field="@nameof(Product.UnitPrice)" Title="Price" DisplayFormat="{0:C}" />
</GridColumns>
</TelerikGrid>
@code {
private TelerikGrid<Product> GridRef { get; set; }
private int? SelectedCategoryId { get; set; }
private async Task OnCategoryChange(int? value)
{
SelectedCategoryId = value;
if (GridRef != null) await GridRef.Rebind();
}
private async Task OnReadProducts(GridReadEventArgs args)
{
// Add SelectedCategoryId to your filter logic
var result = await ProductService.GetProductsAsync(
args.Request.Page,
args.Request.PageSize,
args.Request.Sorts,
SelectedCategoryId);
args.Data = result.Data;
args.Total = result.Total;
}
}- Data vs OnRead: Use
Datafor small in-memory lists; useOnReadfor large or server-backed data. - Edit modes:
GridEditMode.Popup,Inline, orIncell. Popup is common for forms with many fields. - CRUD: You must update the data source in OnCreate/OnUpdate/OnDelete; the Grid does not modify data itself.
- Templates:
contextin<Template>and<EditorTemplate>is the row’s data item. - DisplayFormat:
"{0:C}"for currency,"{0:d}"for dates.