Click here to Skip to main content
15,881,424 members
Articles / Desktop Programming / Windows Forms
Tip/Trick

DataGridViewGrouper

Rate me:
Please Sign up or sign in to vote.
4.95/5 (30 votes)
28 May 2015CPOL3 min read 137.5K   12.2K   39   60
DataGridViewGrouper: add grouping functionality to the .NET DataGridView

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):

C#
var grouper = new Subro.Controls.DataGridViewGrouper(dataGridView1);
grouper.SetGroupOn("AString");

which creates something like:

Image 1

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:

Image 2

The dropdown contains the columns from whatever source the grid is bound to:

Image 3

And the various options can be set via the secondary options button:

Image 4

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:

C#
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:

C#
grouper.SetCustomGroup<TestData>(t => t.AnInt % 10, "Mod 10");

Image 5

Some further examples:

C#
//to start with all rows collapsed on a (re)load or 
//when the group is changed you can set the option startcollapsed:
grouper.Options.StartCollapsed = true;

//to collapse all loaded rows: (the difference with setting the option above, 
//is that after choosing a new grouping (or on a reload), the new groups would expand.
grouper.CollapseAll();

//if you don't want the (rowcount) to be shown in the headers:
grouper.Options.ShowCount = false;

//if you don't want the grouped column name to be repeated in the headers:
grouper.Options.ShowGroupName = false;

//default sort order for the groups is ascending, 
//you can change that in the options as well (ascending, descending or none)
grouper.Options.GroupSortOrder = SortOrder.Descending;

An example of collapse all:

Image 6

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:

C#
//grouper.DisplayGroup += grouper_DisplayGroup;
          
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:

Image 7

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionMulti-column grouping Pin
claudetom018-Mar-24 2:39
claudetom018-Mar-24 2:39 
QuestionPaint Performance ? Pin
nycos6220-Apr-23 5:30
nycos6220-Apr-23 5:30 
Questioncan you please guide, how we can show sum of the column at group level. Pin
muhammad asif jan 202227-Dec-22 1:14
muhammad asif jan 202227-Dec-22 1:14 
AnswerRe: can you please guide, how we can show sum of the column at group level. Pin
nycos6210-Apr-23 12:56
nycos6210-Apr-23 12:56 
QuestionDataGridViewGrouper.dll Pin
Hoàng Nguyễn 202214-May-22 0:24
Hoàng Nguyễn 202214-May-22 0:24 
QuestionDataGridViewGrouper.dll Pin
Junior Augusto Potosme Maliaño28-Oct-21 11:41
Junior Augusto Potosme Maliaño28-Oct-21 11:41 
QuestionDataGridViewGrouper.dll Pin
Member 1338635719-Mar-21 2:38
Member 1338635719-Mar-21 2:38 
Questionrefreshing datasource Pin
GBriotti8-Mar-21 4:31
GBriotti8-Mar-21 4:31 
AnswerRe: refreshing datasource (SOLVED) Pin
GBriotti9-Mar-21 2:35
GBriotti9-Mar-21 2:35 
QuestionRe: refreshing datasource (SOLVED) Pin
Member 133542839-Sep-22 7:14
Member 133542839-Sep-22 7:14 
Questioncan the '+' collapse/expand button be realigned? Pin
GIS Coder27-Jan-21 12:28
GIS Coder27-Jan-21 12:28 
I have a custom edit control I've attached to one of the data columns in my datagridview which requires my row heights to be increased to a minimum of 33 to accommodate the control. Unfortunately, this means the collapsed rows have the '+' collapse/expand button aligned to what looks like the top of the row (which looks odd). Do you have advice for either ...

(1) how to vertically center the collapse/expand button or ...
(2) how to conditionally set the height of the expand/collapse rows to be shorter than the data rows so the expand/collapse buttons and rows appear more normally styled and vertically centered?
QuestionHow to apply it with SQL Statements in c# Pin
Member 1392746927-Oct-19 4:02
Member 1392746927-Oct-19 4:02 
QuestiondataGridViewGrouper HeaderText Pin
Member 1457340927-Sep-19 8:01
Member 1457340927-Sep-19 8:01 
AnswerRe: dataGridViewGrouper HeaderText Pin
Member 1210932918-Nov-20 21:57
Member 1210932918-Nov-20 21:57 
GeneralHow to customize datasoure for group control? Thanks so much! Pin
Member 144814068-Sep-19 18:34
Member 144814068-Sep-19 18:34 
QuestionUse with vb.net Pin
Member 145488942-Aug-19 5:15
Member 145488942-Aug-19 5:15 
QuestionPrevent collapsing in vb.net Pin
Mr.Bluesky7-Sep-18 3:14
Mr.Bluesky7-Sep-18 3:14 
QuestionRemove Grouping Pin
Member 1341448023-Jun-18 22:52
Member 1341448023-Jun-18 22:52 
AnswerRe: Remove Grouping Pin
Member 1447330616-Jul-19 10:27
Member 1447330616-Jul-19 10:27 
QuestionWhen reloading data into DataGridView I am getting exception: Column 'ColumnName' does not belong to table Pin
Luis Mendez26-Jan-18 9:51
Luis Mendez26-Jan-18 9:51 
AnswerRe: When reloading data into DataGridView I am getting exception: Column 'ColumnName' does not belong to table Pin
Member 1447330616-Jul-19 10:25
Member 1447330616-Jul-19 10:25 
QuestionThanks Pin
Luis Mendez24-Jan-18 5:46
Luis Mendez24-Jan-18 5:46 
QuestionConditional Color change Pin
Ziya Hussain3-Jan-18 17:49
Ziya Hussain3-Jan-18 17:49 
QuestionRecompiling for use in VB.net and also how to .GetChanges() Pin
SidupacX13-Nov-17 2:02
SidupacX13-Nov-17 2:02 
QuestionHow to expand and specific group Pin
lrhage10-Oct-17 7:40
lrhage10-Oct-17 7:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.