As it has already been mentioned, the grid supports three methods of data filtering. Two of them enable the developer to filter rows in a grid by setting filtering conditions via IFilter interface or by directly calling Row.Filtered property.

The third method enables the end user to set and edit filters that are located right on columns. When we developed this functionality, we wanted it to be both convenient for end-user and developer and expandable. We didn’t want to add our own data filtering language and therefore used editors based UITypeEditor class that have a good track record.

When a column contains a filter, user sees a small gray icon in its right part. When this icon's color changes to blue, this means that a filter is active and rows are filtered by this column. To cancel filtering over UI you have to click on header in HeaderRowSelector area. When data grouping is used, user can also filter columns or data groups.

There are two styles of editors: DropDown and Modal. When UITypeEditor.EditValue() function is called, editors get a column used for filtering as input and return one of the following values:

Return valueDescription
ColumnFilter hasn‘t been changed during editing
IFilter objectFilter that will be used to verify rows in the specified column.
nullIf null value is returned, no filtering is performed for this column.

This approach covers almost all situations when data filtering may be needed. Filters in column work in parallel with programming filter set via Grid.Filter property. Any of these filters can tell the grid that data should no longer be visible. Data changed in real-time are constantly checked for compliance with filtering conditions and their visibility may change automatically while the application is running. (When data is changed in non-event mode, you should call Row.Update() method)

Grid performs required filter serialization in XML or binary archives, enabling to restore application state when it is restarted.

Below we provide an example of creating an arbitrary column filter that can be used to pick rows with a specific rating.

Dynamic column filters
C# Copy imageCopy
public class RatingFilter : UITypeEditor, IFilter
{
    private Column column;
    private int currentRating = 1;

    public bool IsFiltered(Row row)
    {
        //Indicates where the row math to the column filter
        if (column != null)
        {
            Cell cell = row[column.Id];
            object value = cell != null ? cell.Value : null;
            if (value != null && value is int)
            {
                int rating = (int) value;
                return !(rating == currentRating);
            }
        }
        return false;
    }

    // Occurs when the user changes column filter.
    public event EventHandler<EventArgs> FilterUpdated;

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        //The value is a colum object
        if (value is Column)
        {
            column = (Column) value;
        }

        //Get the editor service
        IWindowsFormsEditorService service = provider.GetService(typeof (IWindowsFormsEditorService)) as IWindowsFormsEditorService;
        if (service != null)
        {
            //Create a control to draw stars
            using (Control control = new Control())
            {
                control.Width = 5 * Properties.Resources.star_grey.Width;
                control.Height = Preferences.Grid.RowDefaultHeight;
                control.BackColor = Color.White;

                //Add callback to draw starts inside the control.
                control.Paint += delegate(object sender, PaintEventArgs e)
                {
                    //Draw a background
                    Rectangle bounds = control.Bounds;
                    using (LinearGradientBrush linearBrush = new LinearGradientBrush(bounds, Color.FromArgb(252, 205, 205), Color.FromArgb(249, 164, 164), LinearGradientMode.Vertical))
                    {
                        e.Graphics.FillRectangle(linearBrush, bounds);
                    }

                    //Draw gold and gray stars
                    bounds.Width = Properties.Resources.star_grey.Width;
                    for (int i = 1; i < 6; i++)
                    {
                        //Select image
                        Image image = i > currentRating ? Properties.Resources.star_grey : Properties.Resources.star_yellow;
                        e.Graphics.DrawImage(image, bounds);
                        bounds.X += bounds.Width;
                    }
                };

                //Add callback to close control when the user ends editing
                control.Click += delegate
                {
                    Point pt = control.PointToClient(Cursor.Position);
                    currentRating = (pt.X - control.Bounds.X) / Properties.Resources.star_grey.Width + 1;
                    service.CloseDropDown();
                };

                //Begin editing
                service.DropDownControl(control);
            }
        }
        return this;
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        //Return the style of the editor
        return UITypeEditorEditStyle.DropDown;
    }
}