DataGrid
A full-featured data grid for Blazor with sorting, filtering, paging, virtual scrolling, grouping, inline editing, row selection, column templates, column reorder, stacked headers, infinite scroll, cell tooltips, copy with headers, conditional formatting, ObservableCollection binding, and CSV/Excel/PDF export. Works in Server, WebAssembly, and Auto render modes.
Installation
dotnet add package Arcadia.DataGrid
Add the stylesheet to your App.razor or _Host.cshtml:
<link href="_content/Arcadia.DataGrid/css/arcadia-datagrid.css" rel="stylesheet" />
No service registration is required. The component is ready to use after adding the package and stylesheet.
Basic Usage
<ArcadiaDataGrid TItem="Employee" Data="@employees">
<ArcadiaColumn TItem="Employee" Title="Name" Field="@(e => e.Name)" />
<ArcadiaColumn TItem="Employee" Title="Department" Field="@(e => e.Department)" />
<ArcadiaColumn TItem="Employee" Title="Salary" Field="@(e => e.Salary)" Format="C0" Align="right" />
</ArcadiaDataGrid>
@code {
private List<Employee> employees = new()
{
new("Alice", "Engineering", 95000),
new("Bob", "Marketing", 72000),
new("Carol", "Engineering", 105000),
};
record Employee(string Name, string Department, decimal Salary);
}
ArcadiaDataGrid Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
Data | IReadOnlyList<TItem>? | null | In-memory collection of row items. When null, the grid shows EmptyMessage |
PageSize | int | 25 | Rows per page. 0 = show all (no paging) |
PageSizeOptions | int[] | [10, 25, 50, 100] | Page size options for the dropdown |
Sortable | bool | true | Enable click-to-sort on column headers. Individual columns can override |
Striped | bool | true | Alternating background shading on even/odd rows |
Hoverable | bool | true | Background highlight on the row under the cursor |
Dense | bool | false | Reduce row height and cell padding for a denser layout |
FixedHeader | bool | true | Keep column headers fixed at the top during vertical scroll. Requires Height |
Height | string? | null | Fixed height with scroll (e.g., "400px"). Null = auto height |
Loading | bool | false | Render animated skeleton rows while awaiting an async fetch |
EmptyMessage | string | "No data available" | Text shown when Data is null or empty and Loading is false |
ShowRowSelector | bool | false | Show row selector column with row numbers and state indicators |
ShowRowNumbers | bool | true | Display row numbers in the row selector column. Requires ShowRowSelector |
Filterable | bool | false | Add a filter input row below headers |
Selectable | bool | false | Allow rows to be selected by clicking |
MultiSelect | bool | false | Add a checkbox column for multi-select. Requires Selectable |
SelectedItems | HashSet<TItem>? | null | Currently selected items. Two-way bindable |
SelectedItemsChanged | EventCallback<HashSet<TItem>> | — | Callback when the selection set changes |
LoadData | EventCallback<DataGridLoadArgs> | — | Server-side data loading callback. When set, the grid operates in server-side mode |
ServerTotalCount | int? | null | Total matching rows on the server for page count calculation. Required with LoadData |
DetailTemplate | RenderFragment<TItem>? | null | Detail row template. When set, rows become expandable |
ChildContent | RenderFragment? | null | Child content slot for ArcadiaColumn components |
SortChanged | EventCallback<SortDescriptor?> | — | Callback when column sorting changes |
OnRowEdit | EventCallback<TItem> | — | Callback when an inline edit is committed (Enter or blur) |
GroupBy | string? | null | Column key whose values group rows into collapsible sections |
VirtualizeRows | bool | false | Enable virtual scrolling for large datasets. Requires Height. Disables pagination |
ItemSize | float | 40 | Estimated row height in pixels for the virtualizer |
OverscanCount | int | 5 | Extra rows rendered outside the viewport to reduce flicker |
Property | string? | null | Property name to use as the unique row identifier for tracking and state persistence |
SelectionMode | SelectionMode | None | Row selection mode: None, Single, Multiple. Replaces Selectable/MultiSelect with a single enum |
BatchEdit | bool | false | Enable batch editing mode. Edits are staged in memory until explicitly committed |
OnBatchCommit | EventCallback<IReadOnlyList<TItem>> | — | Callback when staged batch edits are committed. Receives all modified items |
StateKey | string? | null | Unique key for persisting grid state (sort, filter, page, column order) to browser storage |
OnStateChanged | EventCallback<DataGridState> | — | Callback when grid state changes. Fires on sort, filter, page, or column reorder |
QuickFilter | string? | null | Cross-column search text. Rows where any column value contains this text are shown. Two-way bindable |
QuickFilterChanged | EventCallback<string?> | — | Callback when the quick filter text changes |
ShowToolbar | bool | false | Show the toolbar above the grid with export button, quick filter search, and filter toggle |
ContextMenuTemplate | RenderFragment<TItem>? | null | Template for a custom right-click context menu on rows |
OnContextMenu | EventCallback<DataGridContextMenuArgs<TItem>> | — | Callback when a row is right-clicked. Use to show a custom context menu |
EmptyTemplate | RenderFragment? | null | Custom template shown when Data is null or empty. Overrides EmptyMessage text |
SyncGroup | string? | null | Sync group name for linked chart components. Charts sharing the same SyncGroup synchronize tooltip, crosshair, and zoom state |
Class | string? | null | Additional CSS classes on the root element |
Style | string? | null | Inline style on the root element |
ArcadiaColumn Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
Field | Func<TItem, object>? | null | Value accessor lambda for this column |
Title | string | "" | Column header text |
Sortable | bool? | null | Whether this column is sortable. Null inherits from grid-level Sortable |
Width | string? | null | CSS width (e.g., "200px", "30%"). Null = auto |
Align | string | "left" | Text alignment: left, center, right |
Format | string? | null | .NET format string for cell values (e.g., "C2", "d", "N0") |
Template | RenderFragment<TItem>? | null | Custom cell content template |
HeaderTemplate | RenderFragment? | null | Custom header content template |
Filterable | bool? | null | Whether this column is filterable. Null inherits from grid |
Visible | bool | true | Whether this column is visible |
Frozen | bool | false | Pin this column to the left edge. Requires Width to be set |
Editable | bool | false | Whether this column supports inline editing |
EditTemplate | RenderFragment<TItem>? | null | Custom edit template for inline editing |
Aggregate | AggregateType | None | Footer aggregate: None, Sum, Average, Count, Min, Max |
FooterTemplate | RenderFragment? | null | Custom footer template (overrides Aggregate when set) |
CellClass | Func<TItem, string?>? | null | Dynamic CSS class for cells in this column |
Live Data (ObservableCollection)
The DataGrid automatically detects when Data is an ObservableCollection<T> and re-renders when items are added, removed, or cleared. No manual StateHasChanged() needed.
Basic Usage
@using System.Collections.ObjectModel
<ArcadiaDataGrid TItem="Order" Data="@_orders">
<ArcadiaColumn TItem="Order" Field="@(d => (object)d.Id)" Title="ID" />
<ArcadiaColumn TItem="Order" Field="@(d => (object)d.Product)" Title="Product" />
</ArcadiaDataGrid>
@code {
private ObservableCollection<Order> _orders = new(initialData);
// Adding an item auto-updates the grid — no StateHasChanged needed
private void AddOrder() => _orders.Add(new Order(...));
}
SignalR Integration
// In a Blazor Server component
hubConnection.On<Order>("NewOrder", order =>
{
_orders.Insert(0, order);
// Grid updates automatically!
});
Batch Edit Guard
During batch editing, live updates are suppressed to avoid disrupting the user’s in-progress edits. Updates resume automatically when the batch is committed or discarded.
Debouncing
Rapid changes (e.g., 100 items added in 50ms) are automatically debounced into a single re-render for optimal performance.
Feature Pages
- Sorting — Click-to-sort, multi-direction cycling, SortChanged event
- Filtering — Per-column filter row, FilterDescriptor, operators
- Selection — Single and multi-select, checkbox column, SelectedItems binding
- Editing — Inline editing, EditTemplate, OnRowEdit event
- Grouping — GroupBy column key, collapsible groups
- Templates — Cell, header, footer, detail templates and aggregates
- Virtual Scrolling — Render 10K+ rows at 60fps
- Themes — 6 built-in themes, 3 density modes, CSS custom properties
- Export — CSV export respecting current sort and filters