Sorting

Sorting is enabled by default. Click any column header to cycle through ascending, descending, and unsorted states.

How It Works

  1. Click a column header to sort ascending
  2. Click again to sort descending
  3. Click a third time to clear the sort

The sort indicator appears in the header: an up arrow for ascending, a down arrow for descending, and a neutral icon when unsorted. Headers include aria-sort attributes for screen readers.

Grid-Level vs. Column-Level

The grid-level Sortable parameter (default true) controls the default for all columns. Individual columns can override this with their own Sortable parameter.

@* Grid-level: sorting on by default, but disable it for the Notes column *@
<ArcadiaDataGrid TItem="Employee" Data="@employees" Sortable="true">
    <ArcadiaColumn TItem="Employee" Title="Name" Field="@(e => e.Name)" />
    <ArcadiaColumn TItem="Employee" Title="Salary" Field="@(e => e.Salary)" Format="C0" />
    <ArcadiaColumn TItem="Employee" Title="Notes" Field="@(e => e.Notes)" Sortable="false" />
</ArcadiaDataGrid>

SortChanged Event

Use the SortChanged callback to react to sort changes. The callback receives a SortDescriptor? — the descriptor contains the column key and direction, or null when the sort is cleared.

<ArcadiaDataGrid TItem="Employee" Data="@employees"
                 SortChanged="@OnSortChanged">
    <ArcadiaColumn TItem="Employee" Title="Name" Field="@(e => e.Name)" />
    <ArcadiaColumn TItem="Employee" Title="Salary" Field="@(e => e.Salary)" Format="C0" />
</ArcadiaDataGrid>

<p>Current sort: @sortInfo</p>

@code {
    private string sortInfo = "None";

    private void OnSortChanged(SortDescriptor? sort)
    {
        sortInfo = sort is null
            ? "None"
            : $"{sort.Property} {sort.Direction}";
    }
}

SortDescriptor Type

public class SortDescriptor
{
    public string Property { get; set; }    // Column key (matches Title)
    public SortDirection Direction { get; set; }
}

public enum SortDirection
{
    None,
    Ascending,
    Descending
}

Server-Side Sorting

When using LoadData for server-side data, the sort state is included in the DataGridLoadArgs. The grid does not sort client-side in server mode — your callback is responsible for applying the sort.

<ArcadiaDataGrid TItem="Employee" Data="@employees"
                 LoadData="@LoadEmployees"
                 ServerTotalCount="@totalCount">
    <ArcadiaColumn TItem="Employee" Title="Name" Field="@(e => e.Name)" />
    <ArcadiaColumn TItem="Employee" Title="Salary" Field="@(e => e.Salary)" Format="C0" />
</ArcadiaDataGrid>

@code {
    private List<Employee> employees = new();
    private int totalCount;

    private async Task LoadEmployees(DataGridLoadArgs args)
    {
        // args.SortProperty = "Salary"
        // args.SortDirection = SortDirection.Ascending
        var result = await EmployeeService.QueryAsync(
            skip: args.Skip,
            take: args.Take,
            sortBy: args.SortProperty,
            sortDir: args.SortDirection);

        employees = result.Items;
        totalCount = result.TotalCount;
    }
}

Multi-Column Sort

Beta.10 adds support for sorting by multiple columns simultaneously. This is useful when you need secondary or tertiary sort orders — for example, sorting employees by department first and then by salary within each department.

How Multi-Column Sort Works

  • Shift+Click a column header to add it as an additional sort column. The first column you click normally becomes the primary sort; Shift+Click on subsequent columns adds them as secondary, tertiary, and so on.
  • Click without Shift on any column header to replace all current sorts with a single-column sort on that column. This resets back to single-sort behavior.
  • Sort priority badges appear on each sorted column header, numbered 1, 2, 3, etc., indicating the sort priority order. The badge is omitted when only a single column is sorted.
  • Each sorted column independently cycles through ascending, descending, and unsorted when Shift+Clicked. Removing the last sort column clears all sorts.

Example

<ArcadiaDataGrid TItem="Employee" Data="@employees"
                 Sortable="true"
                 SortChanged="@OnSortChanged">
    <ArcadiaColumn TItem="Employee" Title="Department" Field="@(e => e.Department)" />
    <ArcadiaColumn TItem="Employee" Title="Name" Field="@(e => e.Name)" />
    <ArcadiaColumn TItem="Employee" Title="Salary" Field="@(e => e.Salary)" Format="C0" />
</ArcadiaDataGrid>

<p>Active sorts: @sortSummary</p>

@code {
    private string sortSummary = "None";

    private void OnSortChanged(SortDescriptor? sort)
    {
        // In multi-sort mode, use the SortDescriptors collection
        // on the grid reference for full sort state.
        sortSummary = sort is null
            ? "None"
            : $"{sort.Property} {sort.Direction}";
    }
}

Interaction walkthrough:

  1. Click “Department” header — grid sorts by Department ascending (badge: 1)
  2. Shift+Click “Salary” header — grid sorts by Department ascending, then Salary ascending (badges: 1, 2)
  3. Shift+Click “Salary” again — Salary flips to descending (badges: 1, 2)
  4. Click “Name” without Shift — all multi-sort is cleared, grid sorts by Name ascending only (no badge)

Server-Side Multi-Sort

When using LoadData, the DataGridLoadArgs includes a Sorts collection (IReadOnlyList<SortDescriptor>) containing all active sort descriptors in priority order. The single-sort properties SortProperty and SortDirection remain available and reflect the primary sort for backward compatibility.

Note: Sorting resets the page index to 0 and cancels any active inline edit.