Introduction
The DataGridViewGrouper
is a component that can add grouping functionality to any existing DataGridView
. The component can be added in the designer or in code. Optionally, a control can be used (DataGridViewGrouperControl
) to provide a user interface to alter the grouping.
Background
The component was something I wrote in 2008 and published on blogs.vbcity.com/hotdog/archive/2008/12/19/9225.aspx (no longer available). That was a primary version and although it hasn't been updated in a long time now, the component and its controls are something that I use every day in custom applications and contains a lot of functionality the old version did not.
Using the Code
To simply start grouping, the component can be added in designer, or on the fly. Grouping can be started with one of the appropriate functions, or by attaching a custom grouper.
All the code needed to make a grid grouped on a property (in this example called AString
):
var grouper = new Subro.Controls.DataGridViewGrouper(dataGridView1);
grouper.SetGroupOn("AString");
which creates something like:
N.B.: The test project generates random data, so the displayed data will vary.
The miscellaneous options for formatting/sorting/collapsing/etc. can be set either in code, or with the included wrapper control:
The dropdown contains the columns from whatever source the grid is bound to:
And the various options can be set via the secondary options button:
The options can of course be set in code, but also with the help of an included toolstripmenuitem
which can be added to a contextmenu
or other menu.
In the example, a string
was used, but the same can be accomplished by using a PropertyDescriptor
/DataGridViewColumn
or lambda expression. For example, these do the same as using the string
:
grouper.SetGroupOn<TestData>(t => t.AString);
grouper.SetGroupOn(this.dataGridView1.Columns["AString"]);
Also, a custom grouper can be assigned to the GroupOn
property (any class inheriting GroupingInfo
. This could be changed to an interface later on if needed.
Or by using the SetCustomGroup
method:
grouper.SetCustomGroup<TestData>(t => t.AnInt % 10, "Mod 10");
Some further examples:
grouper.Options.StartCollapsed = true;
grouper.CollapseAll();
grouper.Options.ShowCount = false;
grouper.Options.ShowGroupName = false;
grouper.Options.GroupSortOrder = SortOrder.Descending;
An example of collapse all:
The component exposes a GroupingChanged
event to catch when the grouping was changed or removed. And a DisplayGroup
event which is fired whenever one of the grouping rows is being painted. The DisplayGroup
event can be used to further customize whatever has to be shown:
void grouper_DisplayGroup(object sender, GroupDisplayEventArgs e)
{
e.BackColor = (e.Group.GroupIndex % 2) == 0 ? Color.Orange : Color.LightBlue;
e.Header = "[" + e.Header + "], grp: " + e.Group.GroupIndex;
e.DisplayValue = "Value is " + e.DisplayValue;
e.Summary = "contains " + e.Group.Count + " rows";
}
The snippet above would produce something like:
Points of Interest
The class library is an extract from a larger control library. One of the things still missing here is a quick grouping context menu item, which sets the grouping on the column where the right click took place and is the way grouping is used most in the applications I've used so far. However, the context menu is a bit too integrated in the library and its custom ORM to quickly add here. If interest exists, I will add that later on, including its quick filter options.
Another note: The library also contains some searchboxes (for DataGridView
/Treeview
and bindingsource in general. Not documented here, but fully usable. Just drop onto a form and attach the appropriate control.
History
- 2008: First draft on vbcity blog
- 2015-05-28 First publish of current production version