Step 3: Enable Filtering

  • 4 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.

VirtualSourcesTutorialFiltering

NOTE

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

TIP

Refer to the 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:

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

In Step 1: Fetch Data and Enable Scrolling, you have 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;
}

To Enable Filtering

  1. Implement filtering in the virtual source:

    static IssueFilter MakeIssueFilter(CriteriaOperator filter) {
        return filter.Match(
            binary: (propertyName, value, type) => {
               if(propertyName == "Votes" && type == BinaryOperatorType.GreaterOrEqual)
                   return new IssueFilter(minVotes: (int)value);
               if(propertyName == "Priority" && type == BinaryOperatorType.Equal)
                   return new IssueFilter(priority: (Priority)value);
               if(propertyName == "Created") {
                   if(type == BinaryOperatorType.GreaterOrEqual)
                       return new IssueFilter(createdFrom: (DateTime)value);
                   if(type == BinaryOperatorType.Less)
                       return new IssueFilter(createdTo: (DateTime)value);
                }
                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),
                   priority: filters.Select(x => x.Priority).SingleOrDefault(x => x != null)
               );
           },
           @null: default(IssueFilter)
       );
    }
    
TIP

The code sample above uses the FilterCriteriaMatchHelper.Match method, which allows parsing filter criteria that the GridControl creates.

The FilterCriteriaMatchHelper is an extension of the DevExpress.Xpf.Grid.v19.2.Extensions.dll library, which contains classes whose source code is available to everyone. Refer to c:\Program Files (x86)\DevExpress 19.2\Components\Sources\DevExpress.Xpf.Grid\DevExpress.Xpf.Grid.Extensions\ to learn how extension methods work.

  1. Get a list of priorities to show them in the Priority column's drop-down filter:

    VirtualSourcesPriorities

    source.GetUniqueValues += (o, e) => {
        if(e.PropertyName == "Priority") {
            var values = Enum.GetValues(typeof(Priority)).Cast<object>().ToArray();
            e.Result = Task.FromResult(values);
        } else {
            throw new InvalidOperationException();
        }
    };
    
NOTE

Your service or database may have a special method to get unique values.

  1. Allow filtering in the GridControl by the Priority column's values:

    <dxg:GridColumn FieldName="Priority" AllowedBinaryFilters="Equals"/>
    

    The image below shows the result:

    VirtualSourcesFilteringVotes

  2. Allow filtering in the GridControl by the Votes column's values:

    • Set the ColumnBase.AllowedBinaryFilters property to GreaterOrEqual to allow an end-user to show rows with votes that are greater than or equal to an input value.
    • Set the ColumnBase.FilterPopupMode property to Excel to enable a drop-down filter that allows creating the GreaterOrEqual criteria.
    <dxg:GridColumn FieldName="Votes" AllowedBinaryFilters="GreaterOrEqual" FilterPopupMode="Excel" />
    

    The image below shows the result:

    VirtualSourcesFilteringVotes

  3. Allow filtering in the GridControl by the Created column's values:

    <dxg:GridColumn FieldName="Created" AllowedDateTimeFilters="SingleDateRange" FilterPopupMode="DateSmart" />
    

    The image below shows the result:

    VirtualSourcesFilteringCreated

To Continue or Review