New to Telerik UI for Blazor? Download free 30-day trial

Grid Data Binding

Telerik Blazor Grid is data source agnostic - you can use any database and service according to your project. You only need to get the collection of data models to the Grid in the view-model of the component hosting it.

Basics

There are two main steps to data bind a Grid:

  1. Provide the data. There are two ways to do this:
    • Set the Grid Data parameter. In this case, the Grid will hold all the data and will perform all data operations internally (sorting, paging, filtering, grouping, aggregates, etc.). This approach provides simplicity.
    • Use the Grid OnRead event and pass the data to the event argument. In this case, the Grid will hold only the current page of data items. The component will fire OnRead again for every data operation and expect to receive the expected items. This approach provides flexibility and performance if the total number of data items is large. Also check the Grid-specific OnRead event article.
  2. Configure the Grid to display the data. Again, there are two ways to do this:
    • Generate some or all columns automatically. The autogenerated columns will depend on the Model properties and Data Annotations.
    • Define GridColumn instances and set their Field parameter. The field is required for data and CRUD operations. The field type determines the sorting, filtering and editing behavior. Some columns do not need a field, for example the CommandColumn. To customize data rendering and column behavior, use templates and all the column settings.

Data Sources and Scenarios

The following list of resources provides examples for data binding a grid in various scenarios:

  • Basic example, tutorial video and notes - Grid Bound Columns Overview. Also lists the features (parameters) of a bound column.

  • Optimizing the data source queries - see the Notes section in the article above. In a server-side app, an IQueryable that ties to an appropriate context (such as EntityFramework) that can optimize the LINQ queries the grid generates is a quick option. For full control, use the OnRead event.

  • SQL (or any other) database - you can find examples in our online demos. You can see an offline version of the demos project in the demos folder of your installation (automated or archive). They showcase an EntityFramework context using an SQL database that provides data to a grid through a service, which is a common architecture for decoupling the front-end from the actual data source that you can apply to any database.

    • The CRUD sample project our extensions for Visual Studio and Visual Studio Code can generate for you showcases a similar architecture that you can use as a starting point.

    • The Blazing Coffee sample application shows how to provide data from a SQL (uses SQLite) database to the Grid using Entity Framework Core services.

  • WebAPI data source - you can see how to send an appropriate request for data and return an optimized query in the following sample projects: Grid DataSourceRequest on the server. This is a flexible approach that you can use for any type of service you have - serializing and deserializing the data according to the application logic and needs, and optimizing the database queries on the backend.

  • OData data source - an extension method we provide lets you make OData v4 queries as shown in the following example: Grid and OData.

  • DataTable, ExpandoObject collection - If you don't have actual strongly typed models (yet) and you use ExpandoObject, or your backend comes from an older technology and still returns DataTables, the grid can accommodate such dynamic data types. You can get started from our examples on how to bind the Grid to ExpandoObject collection and bind the Grid to a DataTable, which also support editing.

  • gRPC - the gRPC tooling supports .NET Core, and as of mid-June 2020, there is a package that brings it to WebAssembly. You can find a basic example and more resources to get you started with gRPC in Blazor in the Grid Data from gRPC Sample Project.

  • Foreign Keys - using foreign tables and keys is usually done through the grid templates. You can read more and find examples in the Grid - Foreign Key KnowledgeBase article.

Binding to Interface

Since version 2.27, the Grid supports binding to a collection of multiple model types that implement the same interface.

Note the usage of OnModelInit in the example below. The event handler sets the model type to be used for new items in the Grid. One-type model creation is supported out-of-the-box. If you need to support adding instances of different types:

Data Binding the Grid to an Interface

<TelerikGrid Data="@GridData"
             FilterMode="GridFilterMode.FilterRow"
             EditMode="GridEditMode.Inline"
             OnUpdate="@UpdateHandler"
             OnDelete="@DeleteHandler"
             OnCreate="@CreateHandler"
             OnModelInit="@(() => new Model1())">
    <GridToolBarTemplate>
        <GridCommandButton Command="Add" Icon="@SvgIcon.Plus">Add</GridCommandButton>
    </GridToolBarTemplate>
    <GridColumns>
        <GridColumn Field="IntProperty" />
        <GridCommandColumn>
            <GridCommandButton Command="Edit">Edit</GridCommandButton>
            <GridCommandButton Command="Save" ShowInEdit="true">Save</GridCommandButton>
            <GridCommandButton Command="Cancel" ShowInEdit="true">Cancel</GridCommandButton>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

@code {
    public interface IModel
    {
        public int Id { get; set; }
        public int IntProperty { get; set; }
    }

    public class Model1 : IModel
    {
        public int Id { get; set; }
        public int IntProperty { get; set; }
    }

    public class Model2 : IModel
    {
        public int Id { get; set; }
        public int IntProperty { get; set; }
    }

    List<IModel> GridData { get; set; }

    protected override void OnInitialized()
    {
        var data = new List<IModel>();

        data.Add(new Model1()
        {
            Id = 1,
            IntProperty = 1
        });
        data.Add(new Model2()
        {
            Id = 2,
            IntProperty = 2
        });

       GridData = data;
    }

    public void UpdateHandler(GridCommandEventArgs args)
    {
        var model = (IModel)args.Item;

        var matchingItem = GridData.FirstOrDefault(c => c.Id == model.Id);

        if (matchingItem != null)
        {
            matchingItem.IntProperty = model.IntProperty;
        }
    }

    public void DeleteHandler(GridCommandEventArgs args)
    {
        var model = (IModel)args.Item;

        GridData.Remove(model);
    }

    public void CreateHandler(GridCommandEventArgs args)
    {
        var model = (IModel)args.Item;

        model.Id = GridData.Max(d => d.Id) + 1;

        GridData.Insert(0, model);
    }
}

Up to version 2.26, the Data collection of the Grid must contain instances of only one model type.

See Also

In this article