Blazor-ApexGrid 1.0.0 is here, and it brings the full ApexGrid data grid to .NET. If you build in Blazor, you now get a strongly-typed ApexGrid<TItem> component, with your columns, events, and configuration written in C#, from a single dotnet add package. There is no script tag, no CDN reference, and no npm build step: the grid's JavaScript and styles are bundled into the package and served automatically.

Under the hood it wraps ApexGrid, the Lit-based web-component data grid, and bundles it (with its dependencies) as a self-contained ES module inside the NuGet package. You write Razor and C#; the web component is an implementation detail you never have to wire up.

Key takeaways

  • One install, no JavaScript setup. dotnet add package Blazor-ApexGrid and the grid's JS and CSS are served from _content/Blazor-ApexGrid/ automatically.
  • Strongly typed end to end. A generic ApexGrid<TItem> component, typed GridColumn<TItem> definitions, and typed EventCallbacks for all 27 grid events.
  • A full data grid, not a table. Sorting, filtering, quick filter, local and remote pagination, selection, inline editing with undo/redo, column and row operations, tree data, and master-detail.
  • State persistence built in. Capture the whole view as a JSON snapshot and restore it later, plus a machine-readable schema for driving a view editor or an AI layer.
  • Multi-targets .NET 8, 9, and 10.

Quick start

Because this is a .NET package rather than a JavaScript one, the best way to see it is the code you actually write. Here is a complete grid: define your row type, declare typed columns, and pass configuration objects. A running sample (grid, tree, and master-detail) is deployed at apexcharts.github.io/Blazor-ApexGrid.

@using Blazor_ApexGrid.Components
@using Blazor_ApexGrid.Models

<ApexGrid TItem="Person"
          Data="people"
          Columns="columns"
          Height="360px"
          Pagination="pagination"
          Selection="selection"
          OnRowSelected="OnRowSelected" />

@code {
    private readonly PaginationConfiguration pagination = new() { Enabled = true, PageSize = 10 };

    private readonly GridSelectionConfiguration selection = new()
    {
        Enabled = true, Mode = SelectionMode.Multiple, ShowCheckboxColumn = true,
    };

    private readonly List<GridColumn<Person>> columns = new()
    {
        new() { Key = "name", HeaderText = "Name", Sort = true, Filter = true },
        new() { Key = "age", HeaderText = "Age", Type = GridDataType.Number, Sort = true },
        new() { Key = "role", HeaderText = "Role", Filter = true },
    };

    private List<Person> people = new()
    {
        new() { Name = "Ada Lovelace", Age = 36, Role = "Mathematician" },
        new() { Name = "Alan Turing", Age = 41, Role = "Computer Scientist" },
    };

    private void OnRowSelected(GridRowSelectedEventArgs<Person> e) { /* e.Selected, e.Added, e.Removed */ }

    public class Person
    {
        public string Name { get; set; } = "";
        public int Age { get; set; }
        public string Role { get; set; } = "";
    }
}

Column Key values bind to your row properties by their serialized (camelCase) name, so a Name property is referenced as "name".

Sorting, filtering, and pagination

The data pipeline is on by column flags and tuned by configuration objects. Set Sort and Filter on a column to enable them, then shape the behavior:

<ApexGrid TItem="Person" @ref="grid"
          Data="people" Columns="columns"
          SortConfiguration="new() { Multiple = true, TriState = true }"
          Pagination="new() { Enabled = true, PageSize = 25 }" />

Pagination can be local or remote, and everything is drivable from C# too: SortAsync, ClearSortAsync, FilterAsync, ClearFilterAsync, SetQuickFilterAsync, GotoPageAsync, NextPageAsync / PreviousPageAsync, FirstPageAsync / LastPageAsync, and SetPageSizeAsync.

Inline editing with undo and redo

Editing works in cell or row mode, with a built-in history stack:

<ApexGrid TItem="Person" @ref="grid" Data="people" Columns="columns"
          Editing="editing" OnCellValueChanged="OnEdited" OnHistoryChanged="OnHistory" />

@code {
    private readonly GridEditingConfiguration editing = new()
    {
        Enabled = true, Mode = EditMode.Cell, Trigger = EditTrigger.DoubleClick,
        History = new() { Enabled = true },
    };
}

Mark the columns you want editable with Editable = true, and drive edits and history from code: EditCellAsync, EditRowAsync, CommitEditAsync, CancelEditAsync, UndoAsync, RedoAsync, ClearHistoryAsync, CanUndoAsync, and CanRedoAsync.

Column and row operations

Columns can be pinned, reordered, resized, and shown or hidden: PinColumnAsync, UnpinColumnAsync, MoveColumnAsync, and UpdateColumnsAsync, with ColumnReordering="true" for drag reordering. Rows can be pinned to sticky bands (PinRowAsync / UnpinRowAsync / GetPinnedRowsAsync with RowPinning) and reordered by drag or keyboard (MoveRowAsync with RowReordering).

Tree data and master-detail

Tree data derives its hierarchy from a path array on each row. Point PathKey at that field and no callbacks are needed:

<ApexGrid TItem="Employee" Data="employees" Columns="columns" Tree="tree" />

@code {
    private readonly GridTreeConfiguration tree = new()
    {
        Enabled = true, PathKey = "path", DefaultExpanded = true,
    };
}

Master-detail renders a detail panel from an HTML template whose {field} tokens are replaced with the row's HTML-escaped values:

<ApexGrid TItem="Product" Data="products" Columns="columns" Expansion="expansion" />

@code {
    private readonly GridExpansionConfiguration expansion = new()
    {
        Enabled = true,
        DetailTemplateHtml = "<div style='padding:12px'><strong>{name}</strong> ({category})</div>",
    };
}

Both are drivable from code (ExpandRowAsync, CollapseRowAsync, ToggleRowExpansionAsync, ExpandAllRowsAsync, CollapseAllRowsAsync, and the ...TreeRow... equivalents).

State persistence, and a schema for AI

The grid can capture its entire view (columns, sort, filter, pagination, selection, and more) as a JSON-safe snapshot, and restore it later. Only the slices present in the snapshot are applied, so partial restores work:

var snapshot = await grid.GetStateAsync();   // JSON-safe; persist it anywhere
await grid.SetStateAsync(snapshot);          // restore later

There is also GetSchemaAsync, which returns a machine-readable description of the grid: its columns, available operations, and current state. It is built for driving a view editor, or an AI layer that needs to understand and manipulate the grid programmatically.

Strongly-typed events

Every grid event surfaces as a strongly-typed EventCallback, with selected and affected rows exposed as your own TItem. Version 1.0.0 covers 27 events across the grid:

AreaEvents
SortingOnSorting, OnSorted
FilteringOnFiltering, OnFiltered, OnQuickFilterChanging, OnQuickFilterChanged
PaginationOnPageChanging, OnPageChanged
SelectionOnRowSelecting, OnRowSelected
ColumnsOnColumnPinning, OnColumnPinned, OnColumnMoving, OnColumnMoved
EditingOnCellValueChanging, OnCellValueChanged, OnCellValidationFailed, OnHistoryChanged, OnRowEditStarted, OnRowEditEnded
RowsOnRowPinning, OnRowPinned, OnRowMoving, OnRowMoved
Expansion / treeOnRowExpanding, OnRowExpanded, OnTreeRowExpanding, OnTreeRowExpanded
StateOnStateChanged

Install and requirements

dotnet add package Blazor-ApexGrid

The package is on NuGet and multi-targets .NET 8, 9, and 10. It is a standard Razor component library that uses JSInterop, so it works in Blazor WebAssembly and Blazor Server; the hosted sample runs on WebAssembly. Nothing else is required: the grid's JavaScript and CSS are served automatically from _content/Blazor-ApexGrid/.

Licensing

Blazor-ApexGrid bundles ApexGrid, so it follows the ApexGrid dual-license model. The Community license is free for individuals and organizations with under $2M in annual revenue. Organizations at or above that threshold need a paid Commercial license, and embedding the grid inside a product or platform that others use needs an OEM license. Installing the package means accepting the license that matches your use, so confirm which side of the threshold you are on before you ship.

Summary

Blazor-ApexGrid 1.0.0 puts a complete, strongly-typed data grid in reach of .NET developers with one dotnet add package and no JavaScript plumbing. It ships the full ApexGrid feature set on day one: sorting, filtering, quick filter, pagination, selection, inline editing with undo/redo, column and row operations, tree data, master-detail, and JSON state persistence, all with typed columns and typed callbacks for 27 events. Add the package, drop an ApexGrid<TItem> into a Razor page, and try the live sample or read the source on GitHub. For a recent release on the charting side of the suite, see What's New in ApexGantt 3.15.0.

Frequently asked questions

What is Blazor-ApexGrid?

Blazor-ApexGrid is a Blazor wrapper for ApexGrid, the Lit-based web-component data grid. It gives .NET developers a strongly-typed ApexGrid component with columns, events, and configuration in C#. The core grid (apex-grid 3.3.0 and its dependencies) is bundled as a self-contained ES module and shipped inside the package.

How do I install Blazor-ApexGrid?

Run 'dotnet add package Blazor-ApexGrid'. No other setup is needed: the grid's JavaScript and styles are served automatically from _content/Blazor-ApexGrid/, so there is no script tag, CDN reference, or npm build step.

Which .NET versions does it support?

It multi-targets .NET 8, .NET 9, and .NET 10. It is a standard Razor component library that uses JSInterop, so it works in Blazor WebAssembly and Blazor Server; the hosted sample runs on Blazor WebAssembly.

Is Blazor-ApexGrid free?

It follows the ApexGrid dual-license model. The Community license is free for individuals and organizations with under $2M in annual revenue. Organizations at or above $2M need a paid Commercial license, and redistributing the grid inside a product or platform needs an OEM license.

Does it need a JavaScript build step or npm?

No. The grid's JavaScript and CSS are bundled into the package and served automatically from _content/Blazor-ApexGrid/. You never touch npm, a bundler, or a script tag.

What can the grid do in 1.0.0?

Sorting, filtering, a quick-filter search, local or remote pagination, single or multiple selection, inline cell/row editing with undo and redo, column pin/reorder/resize/hide, row pinning and reordering, tree data, master-detail expansion, and JSON state persistence, all surfaced through strongly-typed callbacks for 27 grid events.