Skip to main content

GridCustomDataSource Class

Allows you to bind the DxGrid to a custom data source.

Namespace: DevExpress.Blazor

Assembly: DevExpress.Blazor.v23.2.dll

NuGet Package: DevExpress.Blazor

Declaration

public abstract class GridCustomDataSource

Remarks

You can bind the grid to data in the following ways:

We recommend that you use the GridCustomDataSource class only if the described ways are not suitable. The example below demonstrates how to implement a custom data source based on the GridCustomDataSource class:

View Example: Bind the Grid to OData Data Source

using System.Collections;
using Blazor.WebAssembly.Models;
using DevExpress.Blazor;
using DevExpress.Data.Filtering;
using DevExpress.Data.Filtering.Helpers;
using Simple.OData.Client;

namespace Blazor.WebAssembly.Services;

public class SimpleODataClientDataSource : GridCustomDataSource {
    private readonly ODataClient _client;
    public SimpleODataClientDataSource(IHttpClientFactory httpClientFactory)
        => _client = new ODataClient(new ODataClientSettings(httpClientFactory.CreateClient("API"), new Uri("odata/", UriKind.Relative)));

    public override async Task<int> GetItemCountAsync(GridCustomDataSourceCountOptions options, CancellationToken cancellationToken)
        => await ApplyFiltering(options.FilterCriteria, _client.For<Post>()).Count()
            .FindScalarAsync<int>(cancellationToken);

    public override async Task<IList> GetItemsAsync(GridCustomDataSourceItemsOptions options, CancellationToken cancellationToken) {
        var filteredClient = ApplyFiltering(options.FilterCriteria, _client.For<Post>().Top(options.Count).Skip(options.StartIndex));
        return (await ApplySorting(options, filteredClient).FindEntriesAsync(cancellationToken)).ToList();
    }

    private static IBoundClient<Post> ApplyFiltering(CriteriaOperator criteria, IBoundClient<Post> boundClient)
        => !criteria.ReferenceEqualsNull() ? boundClient.Filter(ToSimpleClientCriteria(criteria)) : boundClient;

    private static string ToSimpleClientCriteria(CriteriaOperator criteria)
        => $"{criteria}".Replace("[", "").Replace("]", "");

    private static IBoundClient<Post> ApplySorting(GridCustomDataSourceItemsOptions options, IBoundClient<Post> boundClient)
        => options.SortInfo.Any() ? boundClient.OrderBy(options.SortInfo
                .Where(info => !info.DescendingSortOrder).Select(info => info.FieldName).ToArray())
            .OrderByDescending(options.SortInfo
                .Where(info => info.DescendingSortOrder).Select(info => info.FieldName).ToArray()) : boundClient;

    public async Task DeleteAsync(Post instance)
        => await _client.For<Post>().Key(instance.ID).DeleteEntryAsync();

    public async Task AddOrUpdateAsync(Post instance, bool update = false) {
        if (!update) {
            await _client.For<Post>().Set(new { instance.Title, instance.Content }).InsertEntryAsync();
        }
        else {

            await _client.For<Post>().Key(instance.ID).Set(instance).UpdateEntryAsync();
        }
    }
}

During initialization, a GridCustomDataSource descendant sends an additional request to determine the item type. If the item type differs from ExpandoObject, you can specify this type directly in the descendant configuration to avoid additional requests:

private class MyCustomDataSource<T> : GridCustomDataSource {
    protected override Type DataItemType => typeof(T)
    // ...
}

Inheritance

See Also