How to: Create a Custom Filter

  • 3 minutes to read

This document describes how to add a filter to the data used in your application created with the Scaffolding Wizard. This wizard helps you quickly generate an application with the required filtering functionality.

A CollectionViewModel class generated by the Scaffolding Wizard provides the FilterExpression property, which allows you to filter data. Set this property to the required expression.

In this example, the database contains messages of different types: questions, bug reports and suggestions. Your task is as follows:

  • For developers, hide questions and only show bug reports and suggestions;
  • For support engineers, only show questions.

In this case, it is useful to only load items of the required type. To do this, create a set of filters in your View Model.

public partial class IssueCollectionViewModel {
        static readonly IEnumerable<FilterExpressionInfo<Issue>> filters = new FilterExpressionInfo<Issue>[] {
            new FilterExpressionInfo<Issue> ("All",  x => true ),
            new FilterExpressionInfo<Issue> ("For support", x => x.IssueType == IssueType.Question ),
            new FilterExpressionInfo<Issue> ("For developers", x => x.IssueType == IssueType.Bug || x.IssueType == IssueType.Suggestion ),
        };
        public IEnumerable<FilterExpressionInfo<Issue>> Filters { get { return filters; } }
        protected override void OnInitializeInRuntime() {
            base.OnInitializeInRuntime();
            FilterExpression = Filters.First().Expression;
        }
    }
    public class FilterExpressionInfo<TEntity> {
        public FilterExpressionInfo(string displayName, Expression<Func<TEntity, bool>> expression) {
            Expression = expression;
            DisplayName = displayName;
        }
        public Expression<Func<TEntity, bool>> Expression { get; private set; }
        public string DisplayName { get; private set; }
    }

Then, populate an editor with these filters and bind its value to FilterExpression.

<dxb:BarEditItem EditValue="{Binding FilterExpression}">
    <dxb:BarEditItem.EditSettings>
        <dxe:ComboBoxEditSettings ItemsSource="{Binding Filters}" ValueMember="Expression" DisplayMember="DisplayName" IsTextEditable="False"/>
    </dxb:BarEditItem.EditSettings>
</dxb:BarEditItem>

In this case, items will automatically be filtered as soon as the user changes the editor's value.

Here is a screenshot of the updated application.

scaffolding-gs1-05

In order to save the selected filter across application restarts, the IssuesCollectionViewModel implements the ISupportLogicalLayout<string> interface.

public void RestoreState(string state) {
                FilterExpression = Filters.First(f => f.DisplayName == state).Expression;
        }

        public string SaveState() {
                return Filters.First(f => f.Expression == FilterExpression).DisplayName;
        }

Since the CollectionViewModel class implements the non-parameterized base interface ISupportLogicalLayout, only RestoreState and SaveState methods need to be implemented.

TIP

A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=T111346.

You can also learn how to Add advanced end-user filtering functionality to applications.