Blazor-ApexGrid 1.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Blazor-ApexGrid --version 1.2.0
                    
NuGet\Install-Package Blazor-ApexGrid -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Blazor-ApexGrid" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Blazor-ApexGrid" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Blazor-ApexGrid" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Blazor-ApexGrid --version 1.2.0
                    
#r "nuget: Blazor-ApexGrid, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Blazor-ApexGrid@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Blazor-ApexGrid&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Blazor-ApexGrid&version=1.2.0
                    
Install as a Cake Tool

Blazor-ApexGrid

A Blazor wrapper for apex-grid, a Lit-based web-component data grid. The core library (and its dependencies) are bundled into a single self-contained ES module and shipped inside this package, so no <script> tag, CDN reference, or npm build step is required in your app.

  • Typed ApexGrid<TItem> component with strongly-typed columns and events.
  • Data pipeline: sorting, filtering, quick filter, and (local or remote) pagination.
  • Selection: single or multiple, with an optional checkbox column.
  • Inline editing: cell or row mode, with undo/redo history.
  • Column operations: pin, reorder, resize, show/hide.
  • Rows: pinning to sticky bands and drag/keyboard reordering.
  • Tree data and row detail expansion.
  • State persistence: capture and restore a JSON snapshot of the whole view.
  • Multi-targets net8.0, net9.0, and net10.0.

Installation

dotnet add package Blazor-ApexGrid

No other setup is needed: the grid's JavaScript and styles are served automatically from _content/Blazor-ApexGrid/.

Quick start

@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".

Good to know

  • Editing a row in place needs RefreshAsync(). The grid redraws when Data is reassigned or its row count changes. Changing a property on a row already in the list does neither, so call await grid.RefreshAsync() to show the edit.
  • Set RowIdKey when rows have an id. Every change to Data reaches the grid as new objects, so the grid cannot tell a reloaded row from a new one. RowIdKey="id" (the camelCase field name) keeps row pins and a manual row order across data changes, and makes GetStateAsync capture selected and expanded rows by id instead of by position.
  • Body rows are recycled. From 1.2.0 (apex-grid 4.0) a scroll, sort or filter re-binds the rendered row elements, and their cells, to the records now in view instead of building new ones, so a row element can show another record later. Set RowRecycling="false" (rendered as row-recycling="false") to keep each row element with its record, for example when a cell template keeps state in the elements it creates, or when JavaScript interop holds row elements across a scroll or a sort.
  • A data change clears undo history. For the same reason, the grid treats every push of Data (including RefreshAsync()) as new records and drops its undo and redo stacks, since those edits were made to rows it no longer holds.
  • Give the grid a bounded height. Height defaults to 400px. A percentage only works if the parent has a height of its own; otherwise it resolves to zero and the grid renders as nothing.
  • Cell and header templates are JavaScript function strings, passed through AdditionalConfig, not Razor RenderFragments, so a template cannot contain Blazor components.

Columns

GridColumn<TItem> mirrors the core column configuration:

Property Purpose
Key Row field to bind (camelCase property name).
HeaderText Header label (falls back to Key).
Type GridDataType controlling the cell renderer/editor (Number, String, Boolean, Select, Rating, Date, Image, Currency, Avatar, Badge, Progress, Sparkline, Status).
Width, Hidden, Exportable Layout and export.
Pinned, Reorderable, Resizable Column operations.
Sort, Filter Enable sorting/filtering on the column.
Editable Allow inline editing (requires grid Editing).
AdditionalConfig Escape hatch ([JsonExtensionData]) for options not modeled above, including JS-function-string renderers.

Features

Sorting, filtering, pagination

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

Drive them programmatically: SortAsync, ClearSortAsync, FilterAsync, ClearFilterAsync, SetQuickFilterAsync, GotoPageAsync, NextPageAsync/PreviousPageAsync, FirstPageAsync/LastPageAsync, SetPageSizeAsync.

Inline editing with undo/redo

<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 },
    };
}

API: EditCellAsync, EditRowAsync, CommitEditAsync, CancelEditAsync, UndoAsync, RedoAsync, ClearHistoryAsync, CanUndoAsync, CanRedoAsync. Mark editable columns with Editable = true.

ApplyEditsAsync writes a batch of cells by data index. Each write runs the column's validators and raises OnCellValueChanging / OnCellValueChanged, and the whole batch is one undo step and one re-render. It returns a GridApplyEditsResult that counts Applied, Unchanged, Invalid, Cancelled and Skipped separately.

var edits = people.Select((p, i) => new GridCellEdit { DataIndex = i, Column = "age", Value = p.Age + 1 });
var result = await grid.ApplyEditsAsync(edits);   // reaches rows on other pages too

Column and row operations

PinColumnAsync / UnpinColumnAsync / MoveColumnAsync / UpdateColumnsAsync; set ColumnReordering="true" for drag reordering. Rows: PinRowAsync / UnpinRowAsync / GetPinnedRowsAsync (with RowPinning), and MoveRowAsync (with RowReordering).

Tree data

The hierarchy is derived from a path array on each row; point PathKey at that field. No callbacks required.

<ApexGrid TItem="Employee" Data="employees" Columns="columns"
          Tree="new() { Enabled = true, PathKey = &quot;path&quot;, DefaultExpanded = true }" />

Row detail

Expanding a row opens a detail panel beneath it, rendered from an HTML template whose {field} tokens are replaced with the row's (HTML-escaped) values. The panel holds HTML, not a nested grid.

<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> &mdash; {category}</div>",
    };
}

To style elements inside the template from your own CSS, give them a part attribute and list those names in ExportParts; then apex-grid::part(name) reaches them. The panel itself is always apex-grid::part(detail-panel).

Expansion/tree API: ExpandRowAsync, CollapseRowAsync, ToggleRowExpansionAsync, ExpandAllRowsAsync, CollapseAllRowsAsync, and the ...TreeRow... equivalents.

State persistence

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

GetSchemaAsync returns a machine-readable description of the grid (columns, available operations, current state), useful for driving a view editor or an AI layer.

Ignite UI theming

From Blazor-ApexGrid 1.2.0, which bundles apex-grid 4.0, grids can follow the Ignite UI theme the page loads: the brand, text and muted text, gridlines, the header, the state colours, the font, light or dark. It is an add-on, it is free, and it needs no license key. Turn it on once in Program.cs:

using Blazor_ApexGrid;

ApexGridIgniteUI.Enable();

The component then loads _content/Blazor-ApexGrid/js/apex-grid.ignite-ui.bundle.js before the first grid initializes. To load it yourself instead, import it as a module in index.html (or App.razor):

<script type="module" src="_content/Blazor-ApexGrid/js/apex-grid.ignite-ui.bundle.js"></script>

The Ignite UI tokens (--ig-*) rank below everything you set:

Rank Source
1 An --ag-* token you set
2 An --apx-* family token
3 The Ignite UI theme (--ig-*), with the add-on loaded
4 The built-in values

A grid follows the Ignite UI light or dark variant, and a theme swap, live: no refresh call is needed. Per grid:

<ApexGrid TItem="Product" Data="products" Columns="columns" DesignSystem="false" />
<ApexGrid TItem="Product" Data="products" Columns="columns" Tokens="false" />

DesignSystem="false" (rendered as design-system="off") turns the Ignite UI colours and font off; the variant still picks the mode. Tokens="false" (rendered as tokens="off") turns off the family --apx-* tokens and Ignite UI, the variant included, for the grid and the content it renders.

The font comes from --ig-font-family, which is usually a web font, and the Ignite UI theme sheets do not load it. Load the font on the page; the grid lays out in CSS, so it picks the font up when it arrives.

Upgrading from apex-grid 3.x. Before 4.0 the grid read some --ig-* tokens on its own. From 4.0 it reads none without the add-on, so an app that relied on an Ignite UI stylesheet theming the grid calls ApexGridIgniteUI.Enable().

Events

All events surface as strongly-typed EventCallbacks. Payloads use string fields for enum-like values (Blazor's default JSInterop deserialization applies no string-enum converter) and expose selected/affected rows as your TItem.

Area Events
Sorting OnSorting, OnSorted
Filtering OnFiltering, OnFiltered, OnQuickFilterChanging, OnQuickFilterChanged
Pagination OnPageChanging, OnPageChanged
Selection OnRowSelecting, OnRowSelected
Columns OnColumnPinning, OnColumnPinned, OnColumnMoving, OnColumnMoved
Editing OnCellValueChanging, OnCellValueChanged, OnCellValidationFailed, OnHistoryChanged, OnRowEditStarted, OnRowEditEnded
Rows OnRowPinning, OnRowPinned, OnRowMoving, OnRowMoved
Expansion / tree OnRowExpanding, OnRowExpanded, OnTreeRowExpanding, OnTreeRowExpanded
State OnStateChanged

Live demo

A running sample (data grid, plus tree and row detail) is deployed at https://apexcharts.github.io/Blazor-ApexGrid/. Source is under src/Blazor-ApexGrid.Sample.

License

This wrapper bundles apex-grid, which is offered under the ApexCharts dual-license model: a Community License at no cost for individuals, non-profits, educators and organizations under $2M USD in annual revenue, operating budget or funding, and a paid Commercial or OEM license at or above that. Embedding the grid in a product or platform used by other people needs the OEM License whatever your size. See LICENSE.md for the full terms.

Built on top of apex-grid v4.0.0.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.1 39 11/10/2026
1.2.0 55 11/9/2026
1.2.0-beta.1 50 11/8/2026
1.1.0 110 10/31/2026
1.0.1 103 10/31/2026
1.0.0 246 7/7/2026

1.2.0 Bundles apex-grid 4.0.0 (was 3.6.0). New: opt-in Ignite UI theming, turned on once with ApexGridIgniteUI.Enable(); per grid, DesignSystem="false" turns the Ignite UI colours and font off and Tokens="false" turns off the family --apx-* tokens too. Japanese and other IME input now works in the cell editor, filter panel and quick filter, and the filter reads numbers typed in full width or with the grouping of the column locale. Behaviour to note: body rows are recycled on scroll, sort and filter, and RowRecycling="false" turns that off; an Ignite UI stylesheet on the page no longer re-tints the grid brand or replaces its font until ApexGridIgniteUI.Enable() is called; the grid role and row counts moved from the apex-grid host to its inner table part; with pagination, pinned rows no longer count toward the pages.