The requested page is not available for the requested platform. You are viewing the content for Default platform.

Step 3: Enable Filtering

  • 3 min to read

In this step, you enable the filtering functionality in the GridControl bound to a virtual source.


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 MainPage() {
    // ... 
    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:

    • Get the GridControl's filtering using the DevExpress.Data.FetchEventArgsBase.Filter property.
    • Parse filtering and return a filter. The DevExpress.Data.InfiniteAsyncSource.FetchRows event handler takes into account this filter when fetching rows.
        static IssueFilter MakeIssueFilter(CriteriaOperator filter) {
            return filter.Match(
                binary: (propertyName, value, type) => {
                    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)

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

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

    • Handle the DevExpress.Data.InfiniteAsyncSource.GetUniqueValues event.
    • Get a list of priorities and specify the DevExpress.Data.GetUniqueValuesAsyncEventArgs.Result property.
            source.GetUniqueValues += (o, e) => {
                if (e.PropertyName == "Priority") {
                    var values = Enum.GetValues(typeof(Priority)).Cast<object>().ToArray();
                    e.Result = Task.FromResult(values);
                else if (e.PropertyName != "Created") {
                    throw new InvalidOperationException();

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

  3. Allow filtering in the GridControl by the Priority and Created columns values:

            <Grid:GridDateColumn FieldName="Created" AllowSorting="True" AllowColumnFiltering="True" FilterPopupMode="DateSmart"/>
            <Grid:GridTextColumn FieldName="Priority" AllowColumnFiltering="True" />