Blazor QuickGrid with WebAssembly and API backend – complete example, Part 2

In the previous post, I covered the basics of implementing QuickGrid and also implemented paging. In this post, I will cover virtualisation,  filtering, and sorting. To follow along, you can check out the code and switch to the Implemented-Paging branch, where we stopped in the last post.

Implement virtualization

Virtualization lets you scroll smoothly through a large data set, but only loads and shows the visible rows on the screen. This can make your grid feel very fast, even with a lot of data. QuickGrid’s virtualization feature uses Blazor’s built-in Virtualize component, so it has the same limitations.

To turn on virtualization, you must set Virtualize=“true” on the QuickGrid component. You also need to ensure that every row has the same fixed height. If you don’t, you could encounter strange issues while scrolling.

It’s a bit difficult to see the virtualization, but you’ll notice it if you set the page size to 50 and quickly scroll down.

The code up to here can be found on the Implemented-Virtualization branch.

Implement filtering

QuickGrid does not have built-in filtering APIs because you can easily create your own UI for controlling what data to include and then use that with your data source.

The UI to control what data to include can be placed anywhere and be built using regular Blazor components and binding. You can also use QuickGrid’s ColumnOptions feature to put the filtering UI inside a popup linked to a specific column, which is the approach we will take.

First, declare three fields in the @code section to store the filter values for the name, email address and user name columns.

string nameFilter;
string emailAddressFilter;
string userNameFilter;

Next, add a new property to filter the customers based on what is stored in the filters.

private IQueryable<Customer>? filteredCustomers
        if (customers is null)
            return null;

        var result = customers;

        if (!string.IsNullOrEmpty(nameFilter))
            result = result.Where(c => c.Name.ToLowerInvariant().Contains(nameFilter.ToLowerInvariant()));

        if (!string.IsNullOrEmpty(emailAddressFilter))
            result = result.Where(c => c.EmailAddress.ToLowerInvariant().Contains(emailAddressFilter.ToLowerInvariant()));

        if (!string.IsNullOrEmpty(userNameFilter))
            result = result.Where(c => c.UserName.ToLowerInvariant().Contains(userNameFilter.ToLowerInvariant()));

        return result;

Next, we need to update the QuickGrid component to refer to this new filteredCustomers property and then set up the UI with input elements that will bind to the filter fields. The complete component’s code will now be:

<QuickGrid Items="@filteredCustomers" Pagination="@paginationState" Virtualize="true">
    <TemplateColumn Title="Avatar">
        <img width="50" src="@context.Avatar" alt="Customer avatar" />
    <PropertyColumn Property="@(p => p.Name)">
            <input class="form-control" type="search" autofocus @bind="nameFilter" @bind:event="oninput" placeholder="Filter..." />
    <PropertyColumn Property="@(p => p.EmailAddress)">
            <input class="form-control" type="search" autofocus @bind="emailAddressFilter" @bind:event="oninput" placeholder="Filter..." />
    <PropertyColumn Property="@(p => p.UserName)">
                <input class="form-control" type="search" autofocus @bind="userNameFilter" @bind:event="oninput" placeholder="Filter..." />

Time to test the changes out. We’ll search for everyone with a name containing “marvin”, an email address containing “hotmail” and the number “7” in their user name.

The code up to here can be found on the Implemented-Filtering branch.

Implement sorting

Columns are used to determine how sorting works. If you have a PropertyColumn, you can enable sorting by setting Sortable=“true”. If you have a TemplateColumn, you can enable sorting by providing a value for the column’s SortBy parameter. If you have a custom column that inherits from ColumnBase, you can also enable sorting by setting Sortable=“true” or by overriding IsSortableByDefault and returning true. You can also set InitialSortDirection on a column to SortDirection.Ascending or SortDirection.Descending to indicate the initial sort order of the grid.

We only need to sort by PropertyColumn’s, but we’ll set the InitialSortDirection for the email address and user name columns for demo purposes. 

Add the following to the name PropertyColumn:


Add the following code to the email address PropertyColumn:

Sortable="true" InitialSortDirection="SortDirection.Ascending"

Add the following to the user name PropertyColumn:

Sortable="true" InitialSortDirection="SortDirection.Descending"

Run the projects, and you should see the following:

The code up to here can be found on the Implemented-Sorting branch.

That’s all I’ll cover in this post to prevent it from getting too long. In the next post, we’ll go over implementing paging, filtering and sorting via the API so that we do not need to pull all the data before rendering the component.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.