Custom ID Field
Configure the ID field for stable row identification across data updates, sorting, and pagination. This is critical for maintaining selection state when data changes.
Why IdField Matters
- Selection persists across data updates and pagination
- Rows maintain stable identity during sorting/filtering
- Default is "Id" (C# convention) - works with most models
- Customize for models with different primary key names
0 product(s) selected
View Code
// Model with custom ID field
public class Product
{
public Guid ProductId { get; set; } // ← Custom ID field
public string Name { get; set; }
public decimal Price { get; set; }
}
<Grid Items="@products"
SelectionMode="GridSelectionMode.Multiple"
IdField="ProductId"
@bind-SelectedItems="@selectedProducts">
<Columns>
<GridColumn Field="ProductId" Header="ID" />
<GridColumn Field="Name" Header="Product" />
</Columns>
</Grid>
// Common ID field patterns:
// IdField="Id" // Default (C# convention)
// IdField="ProductId" // Specific entity ID
// IdField="OrderId" // Another entity
// IdField="_id" // MongoDB convention
// IdField="id" // JavaScript conventionSingle Row Selection
Radio-style single row selection with visual feedback.
No order selected
View Code
<Grid Items="@orders"
SelectionMode="GridSelectionMode.Single"
@bind-SelectedItems="@selectedOrders">
<Columns>...</Columns>
</Grid>
@if (selectedOrders.Count > 0)
{
var order = selectedOrders.First();
<p>Selected: @order.Customer</p>
}Multiple Row Selection
Checkbox-based multiple row selection with select all functionality.
View Code
<Grid Items="@orders"
SelectionMode="GridSelectionMode.Multiple"
@bind-SelectedItems="@selectedOrders">
<Columns>...</Columns>
</Grid>
<Button OnClick="DeleteSelected">Delete Selected</Button>
@code {
private void DeleteSelected()
{
// Remove selected items from the list
orders.RemoveAll(o => selectedOrders.Contains(o));
selectedOrders = Array.Empty<Order>();
}
}Controlled Selection State
Programmatic control of selection with external buttons.
0 row(s) selected programmatically
View Code
<Button OnClick="SelectHighValueOrders">Select High Value</Button>
<Grid Items="@orders"
SelectionMode="GridSelectionMode.Multiple"
@bind-SelectedItems="@selectedItems">
<Columns>...</Columns>
</Grid>
@code {
private IReadOnlyCollection<Order> selectedItems = Array.Empty<Order>();
private void SelectHighValueOrders()
{
// Set selection programmatically
selectedItems = orders.Where(o => o.Amount > 5000).ToList();
}
private void ClearSelection()
{
selectedItems = Array.Empty<Order>();
}
}Tracked Observable Collection (Automatic Delta Updates)
Grid automatically detects and applies delta changes when using TrackedObservableCollection. Only changed rows are updated - no full grid refresh needed!
Performance Benefits
- Delta Updates: Only modified rows are re-rendered (not entire grid)
- Selection Preserved: Row selection survives data changes automatically
- Natural Mutations: Modify items directly, then call NotifyItemsChanged()
- Batching: Multiple rapid changes are batched together (100ms window)
- Efficient: Uses AG Grid's transaction API for minimal DOM updates
View Code
@using BlazorUI.Components.Grid
@code {
// Use TrackedObservableCollection for automatic delta updates
private TrackedObservableCollection<Order> orders = new();
private IReadOnlyCollection<Order> selectedOrders = Array.Empty<Order>
protected override void OnInitialized()
{
// Initialize with data
var data = GridDemoData.GenerateOrders(50);
orders = new TrackedObservableCollection<Order>(data);
}
private void DeleteSelected()
{
// Remove items - Grid automatically detects and applies transaction
foreach (var order in selectedOrders.ToList())
{
orders.Remove(order); // ← Triggers CollectionChanged event
}
selectedOrders = Array.Empty<Order>
}
private void AddOrder()
{
// Add item - Grid automatically applies transaction
orders.Add(new Order { ... }); // ← Triggers CollectionChanged event
}
private void UpdateOrder()
{
// Get a random order and modify it directly
var order = orders[Random.Shared.Next(orders.Count)];
// Modify properties naturally
order.Amount = Random.Shared.Next(100, 10000);
order.Status = RandomStatus();
// Notify grid that this item changed
orders.NotifyItemsChanged(order); // ← Triggers ItemsChanged event → Grid.transaction
}
}