Step 3: Enable Filtering

  • 3 minutes to read

You should enable data operations after binding the GridControl to a virtual source.

In this step, we describe how to enable the filtering feature:

  • You implement the filtering data operations in the virtual source.
  • Then you enable these data operation in the GridControl.

VirtualSourcesAdvancedTutorialFiltering

NOTE

The Issues Service is used as an example of a data source in this tutorial.

TIP

Refer to the Step 4: Enable Search Panel topic to learn how to enable the Search Panel in the GridControl bound to a virtual source.

Overview

The Issues Service can fetch rows:

  • Over a period of time (between CreatedFrom and CreatedTo).
  • With a maximum or minimum number of Votes.
  • With a specified Tag.
public class IssueFilter {
    public DateTime? CreatedFrom { get; private set; }
    public DateTime? CreatedTo { get; private set; }
    public int? MinVotes { get; private set; }
    public int? MaxVotes { get; private set; }
    public string Tag { get; private set; }
}

In Step 1: Fetch Data and Enable Scrolling, you fetched rows without filtering:

public MainWindow() {
    // ...
    source.FetchRows += (o, e) => {
        e.Result = FetchRowsAsync(e);
    };
}
static async Task<FetchRowsResult> FetchRowsAsync(FetchRowsAsyncEventArgs e) {
    IssueFilter filter = MakeIssueFilter(e.Filter);
    const int pageSize = 30;
    var issues = await IssuesService.GetIssuesAsync(
        page: e.Skip / pageSize,
        pageSize: pageSize,
        sortOrder: IssueSortOrder.Default,
        filter: filter);
    return new FetchRowsResult(issues, hasMoreRows: issues.Length == pageSize);
}
static IssueFilter MakeIssueFilter(CriteriaOperator filter) {
    return null;
}

Enable Filtering

  1. Implement filtering in the virtual source:

    static IssueFilter MakeIssueFilter(CriteriaOperator filter) {
        return filter.Match(
            binary: (propertyName, value, type) => {
                switch(propertyName) {
                    case "Votes":
                        if(type == BinaryOperatorType.GreaterOrEqual)
                            return new IssueFilter(minVotes: (int)value);
                        if(type == BinaryOperatorType.LessOrEqual)
                            return new IssueFilter(maxVotes: (int)value);
                        throw new InvalidOperationException();
                    case "Created":
                        if(type == BinaryOperatorType.GreaterOrEqual)
                            return new IssueFilter(createdFrom: (DateTime)value);
                        if(type == BinaryOperatorType.Less)
                            return new IssueFilter(createdTo: (DateTime)value);
                        throw new InvalidOperationException();
                    case "Tags":
                        if(type == BinaryOperatorType.Equal)
                            return new IssueFilter(tag: (string)value);
                        throw new InvalidOperationException();
                    default:
                        throw new InvalidOperationException();
                }
            },
            and: filters => {
                return new IssueFilter(
                    createdFrom: filters.Select(x => x.CreatedFrom).SingleOrDefault(x => x != null),
                    createdTo: filters.Select(x => x.CreatedTo).SingleOrDefault(x => x != null),
                    minVotes: filters.Select(x => x.MinVotes).SingleOrDefault(x => x != null),
                    maxVotes: filters.Select(x => x.MaxVotes).SingleOrDefault(x => x != null),
                    tag: filters.Select(x => x.Tag).SingleOrDefault(x => x != null)
                );
            },
            @null: default(IssueFilter)
        );
    }
    
  2. Get a list of tags to show them in the Tags column's drop-down filter:

    VirtualSourcesAdvancedTutorialTags

    source.GetUniqueValues += (o, e) => {
        e.Result = GetUniqueValuesAsync(e.PropertyName);
    };
    static async Task<object[]> GetUniqueValuesAsync(string propertyName) {
        if(propertyName == "Tags")
            return await IssuesService.GetTagsAsync();
        throw new InvalidOperationException(); 
    }
    
  3. Allow filtering in the GridControl:

    <dxg:GridColumn FieldName="Created" AllowedDateTimeFilters="SingleDateRange" FilterPopupMode="DateSmart" />
    <dxg:GridColumn FieldName="Votes" AllowedBinaryFilters="GreaterOrEqual,LessOrEqual" FilterPopupMode="Excel" />
    <dxg:GridColumn FieldName="Tags" AllowedBinaryFilters="Equals" />
    

    Now the GridControl allows you to filter data. Note that an error occurs if you apply a filter with incompatible sorting. Refer to the Step 5: Consider Sort and Filter Restrictions to learn more.

Continue or Review