FlexGrid for WPF | ComponentOne
Features / Data Filtering / Excel-like Filtering
In This Topic
    Excel-like Filtering
    In This Topic

    FlexGrid provides Excel-like filtering feature to filter data through drop down/ellipsis icon in column headers. It adds Excel-style filtering UI to each column that allows you to apply different filters to filter data.

    Excel-like filtering is available in FlexGrid through a separate control called FlexGridFilter, which is implemented through an extender assembly, C1.WPF.FlexGridFilter. Once the FlexGridFilter control is added, the grid displays a drop-down icon on hovering the column headers. The drop-down icon shows an editor that allows users to specify filters on columns. Users may choose between the two types of filters:

    • Value filter: This filter lets you filter specific values in the column.
    • Condition filter: This filter lets you specify conditions composed of an operator (greater than, less than, etc.) and a parameter. The conditions can be combined using an AND or an OR operator.
    Note: Filtering using FlexGridFilter is only available in .NET Framework version. 

    The images below show the filters displayed on clicking the drop-down icon.

    To enable filtering through FlexGridFilter

    You can enable filtering in FlexGrid by manually adding the C1.WPF.FlexGridFilter assembly to your project, creating an object of the C1FlexGridFilter class, and attaching this object to an existing FlexGrid object as illustrated in the following code snippets. You can use either of the XAML or C# code to enable filtering:

    XAML
    Copy Code
    <c1:C1FlexGrid Name="grid" >
      <!-- add filtering support to the control: -->
      <c1:C1FlexGridFilterService.FlexGridFilter>
        <c1:C1FlexGridFilter />
      </c1:C1FlexGridFilterService.FlexGridFilter>
    </c1:C1FlexGrid>
    
    C#
    Copy Code
    // create a FlexGrid
    var grid = new C1FlexGrid();
    //enable filtering through FlexGridFilter
    var gridFilter = new C1FlexGridFilter(grid);
    

    To select filter mode

    The filter operates in two modes depending on the value of the UseCollectionView property. If the UseCollectionView property is set to false, rows that do not satisfy the filter are hidden (the filter sets their Visible property to false). In this mode, the filter has no effect on the row count. You can use this mode in bound and unbound grids.

    If the filter's UseCollectionView property is set to true, the filter gets applied to the data source. In this mode, changes to the filter affect the number of items exposed by the data source to the grid and to any other controls bound to the same data source. This filtering mode can only be used in bound grids.

    XAML
    Copy Code
    <c1:C1FlexGrid Name="grid" >
      <!-- add filtering support to the control: -->
      <c1:C1FlexGridFilterService.FlexGridFilter>
        <c1:C1FlexGridFilter UseCollectionView="True">
      </c1:C1FlexGridFilterService.FlexGridFilter>
    </c1:C1FlexGrid>
    
    C#
    Copy Code
    // create C1FlexGrid
    var grid = new C1FlexGrid(); 
    
    // enable filtering on the grid
    var gridFilter = new C1FlexGridFilter(grid);
    
    // filter at the data source level
    gridFilter.UseCollectionView = true;
    

    To customize filter type for each column

    By default, filters are enabled for every column. Columns that contain Boolean or enumerated data get a value filter, and columns that contain other data types get value and condition You can use the FilterType property to change this behavior and specify the type of filter to enable for each column.

    Specifying the filter type is important in scenarios where columns have a large number of unique values or when columns contain bindings that do not work with the filters. For example, columns containing images cannot be filtered with value or condition filters. In this case, you would disable the filter by setting the FilterType property to None.

    A grid containing several thousand items may have a unique ID column, which adds too many items to the value filter, making it slow and not very useful. In this case, disable the value filter by setting the FilterType property to Condition.

    The code below shows how to accomplish this:

    C#
    Copy Code
    // create C1FlexGrid
    var grid= new C1FlexGrid();
    
    // enable filtering on the grid
    var gridFilter = new C1FlexGridFilter(grid);
    
    // disable filtering on the Image column
    var columnFilter = gridFilter.GetColumnFilter(flex.Columns["Image"]);
    columnFilter.FilterType = FilterType.None;
    
    // disable value filtering on the ID column
    columnFilter = gridFilter.GetColumnFilter(flex.Columns["ID"]);
    columnFilter.FilterType = FilterType.Condition;
    

    To specify filter type in code

    In most cases, users set the filters. But the ColumnFilter class exposes a full object model that enables developers to customize filter conditions through code. For example, the code below applies a filter to the second column. The filter causes the grid to show items where the value in the second column contains the letter Z:

    C#
    Copy Code
    // create C1FlexGrid
    var grid = new C1FlexGrid();
    
    // enable filtering on the grid
    var gridFilter = new C1FlexGridFilter(grid);
    
    // get filter for the first column
    var columnFilter = gridFilter.GetColumnFilter(grid.Columns[0]);
    
    // create filter condition (Contains 'z')
    var condition = columnFilter.ConditionFilter.Condition1;
    condition.Operator = ConditionOperator.Contains;
    condition.Parameter = "z";
    
    // apply the filter 
    gridFilter.Apply();
    

    To persist filters

    The C1FlexGridFilter class contains a FilterDefinition property that gets or sets the current filter state as an XML string. You can use this string to persist the filter state when the user quits the application, so that it can be restored later. You may also save several filter definitions, and allow the user to select and then customize these pre-set filters. You can also save and restore filter definitions to streams using the SaveFilterDefinition and LoadFilterDefinition methods.

    Note: The C1.WPF.FlexGridFilter extender assembly is shipped separately with FlexGrid due to following reasons:

    • To minimize the footprint of FlexGrid assembly.
    • To provide complete flexibility in choosing extensions.
    • To extend the functionality of the C1FlexGrid class through custom codes.

    Excel-like filtering is available in FlexGrid by default, and the column FilterLoading event allows you to customize the filtering behavior and allows you to display conditional filters, by default. It lets you to get the data filter to be displayed for column filtering using the DataFilter property. This filter can then be added to the column for filtering values. Contrastingly, you can disable the filtering on any column by setting its AllowFiltering property to false.

    By default, the numeric (conditional) filters are enabled for every column with numeric data. In addition, you may choose to display value filter for the columns with Boolean or enumerated data and display a combination of value and conditional filters for the columns that contain the data of other data types as showcased in the following code. Here, the value filter lets you filter specific values in the column and the conditional filter lets you specify conditions composed of an operator (greater than, less than, etc.) and a parameter. The conditions can be combined using an AND or an OR operator.

    Excel like Filtering in WPF FlexGrid

    The following code uses the Customer class created in Quick Start. Here, the FlexGrid columns are bound to the customer's first name, last name, order total, order count, country id, last order date, and last order time as shown in the following XAML code.

     

    XAML
    Copy Code
    <c1:FlexGrid x:Name="grid" AutoGenerateColumns="False">
        <c1:FlexGrid.Columns>
            <c1:GridColumn Binding="FirstName"/>
            <c1:GridColumn Binding="LastName"/>
            <c1:GridColumn Binding="OrderTotal" Format="C2"/>
            <c1:GridColumn Binding="OrderCount" Format="N1" FilterLoading="Order_FilterLoading"/>
            <c1:GridColumn Binding="CountryId" Header="Country Id" FilterLoading="Country_FilterLoading"/>
            <c1:GridDateTimeColumn Binding="LastOrderDate" Mode="Date"/>
            <c1:GridDateTimeColumn Binding="LastOrderDate" Header="Last Order Time" Mode="Time"/>
        </c1:FlexGrid.Columns>
    </c1:FlexGrid>
    

    To display value filter and conditional filters on the grid created above, use the following code:

    C#
    Copy Code
    private List<Customer> _data;
    public ExcelFiltering()
    {
        InitializeComponent();
    
        _data = Customer.GetCustomerList(100).ToList(); 
        // For displaying value filter.
        grid.Columns[4].DataMap = new C1.WPF.Grid.GridDataMap { ItemsSource = Customer.GetCountries(), DisplayMemberPath = "Key", SelectedValuePath = "Key" }; 
        grid.ItemsSource = _data;
    }
    
    private void Country_FilterLoading(object sender, C1.WPF.Grid.GridColumnFilterLoadingEventArgs e)
    {
         e.DataFilter.Filters.Add(new NumericFilter() { PropertyName = "CountryId" });
         e.ShowApplyButton = true;
         e.ShowClearButton = true;
    }
    
    private void Order_FilterLoading(object sender, C1.WPF.Grid.GridColumnFilterLoadingEventArgs e)
    {
        // Numeric (Conditional) filter is displayed by default for Numeric data.
        e.ShowApplyButton = true;
        e.ShowClearButton =true;
    }
    

    Multi-value filtering

    In FlexGrid, you can easily filter a specific value from a column using Filter property but, sometimes, you may want to filter multiple values from a single column containing large data. For such situations, you can use the multi-value filtering to explicitly set a specific filter type for a column. FlexGrid allows you to apply multi-value filtering on a column to filter out relevant information from large data. In multi-value filtering, a checked list of possible values is displayed allowing you to select the values you wish to filter out of the view. This is a good option for columns where you have several unique and repeated values (like a category or type field). Let's say, you have a huge list of countries in your database and want to expand your business in specific countries. In such scenarios, you can apply multi-value filtering on your data to filter out the customers and get their contact details. The following example shows how you can achieve this by applying multi-value filtering to the Country column in FlexGrid.

    The following GIF shows how multi-value filtering can be used in FlexGrid to select multiple countries at runtime.

    WPF FlexGrid displaying multi-value filtering in string field.

    You can apply multi-value filtering in FlexGrid by using the FilterType property of the ColumnFilter class to set the filter type to Value using the FilerType enumeration.

    Use the following code snippet to enable multi-value filtering for the Country column.

    C#
    Copy Code
    //Enable filtering through FlexGridFilter
    var gridFilter = new C1FlexGridFilter(grid);
    var columnFilter = gridFilter.GetColumnFilter(flex.Columns["Country"]);
    columnFilter.FilterType = FilterType.Value;
    

    The following GIF shows how multi-value filtering can be used in FlexGrid to select multiple countries at runtime.

    WPF FlexGrid displaying multi-value filtering in string field

    To apply multi-value filtering a column, say Country, you can generate the FilterLoading event for it. In the FilterLoading event, create an instance of the ChecklistFilter class and add it to the FilterCollection to explicitly set the checklist filter type for the Country column as shown in the following code. The following code uses the Customer class created in Quick Start.

    C#
    Copy Code
    private void Country_FilterLoading(object sender, C1.WPF.Grid.GridColumnFilterLoadingEventArgs e)
        {
            e.DataFilter.Filters.Clear();
            C1.WPF.DataFilter.ChecklistFilter filter = new C1.WPF.DataFilter.ChecklistFilter();
            List<object> filterList = new List<object>();
                    foreach (Customer data in grid.ItemsSource)
                filterList.Add(data.Country);
                filter.ItemsSource = filterList;
                filter.PropertyName = "Country";
                e.DataFilter.Filters.Add(filter);
        }
    
    See Also