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.
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)
{
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;
}
public event EventHandler<EventArgs> FilterUpdated;
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
if (value is Column)
{
column = (Column) value;
}
IWindowsFormsEditorService service = provider.GetService(typeof
(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if (service != null)
{
using (Control control = new Control())
{
control.Width = 5 * Properties.Resources.star_grey.Width;
control.Height = Preferences.Grid.RowDefaultHeight;
control.BackColor = Color.White;
control.Paint += delegate(object sender, PaintEventArgs e)
{
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);
}
bounds.Width = Properties.Resources.star_grey.Width;
for (int i = 1; i < 6; i++)
{
Image image = i > currentRating
? Properties.Resources.star_grey
: Properties.Resources.star_yellow;
e.Graphics.DrawImage(image, bounds);
bounds.X += bounds.Width;
}
};
control.Click += delegate
{
Point pt = control.PointToClient(Cursor.Position);
currentRating = (pt.X - control.Bounds.X) /
Properties.Resources.star_grey.Width + 1;
service.CloseDropDown();
};
service.DropDownControl(control);
}
}
return this;
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
}
Back to .Net Grid Features