Skip to main content

DevExpress v24.2 Update — Your Feedback Matters

Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

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.

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