Graphical Filters in Columns

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.

 Graphical Filters in Columns

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 value Description
Column Filter hasn‘t been changed during editing
IFilter object Filter that will be used to verify rows in the specified column.
null If 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.


    
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;
}
}

 

Back to .Net Grid Features