HotDog's Blog

Hotdog (Robert Verpalen) about C# and vb.net

vbCity Blogs moved to:
http://cs.vbcity.com/blogs
  Home :: Syndication  :: Login

OctNovember 2009Dec
SMTWTFS
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Articles

Archives

Topics

CONTACT

Fun but useful linkies

General

VS 2005

Wolfenstein ET

Complete Source Code: http://blogs.vbcity.com/hotdog/archive/2008/12/19/9225.aspx


Note: the code is now rewritten to be 2.0 compatible (the project was written in vs2008 with compatibility set on framework 2.0), but older designers may still have trouble compiling because of the use of newer syntax (such as automatic properties). All 'var' keywords should be replaced, but they tend to sneak in because they are so easy to use ;)
If the newer syntax is a problem for many of you, drop me a note and I'll try to remove all of those syntaxes too.

Example:
Assuming you have a form with a datagridview called dataGridView1, add this code (after setting its datasource):

Code CopyHideScrollFull
var grouper = new Subro.Controls.DataGridViewGrouper(dataGridView1);
grouper.SetGroupOn("NameOfThePropertyToGroupOn");
. . .

Functionality:
The DataGridViewGrouper is a component that can be added in the forms designer or in runtime to add grouping to any existing (databound) DataGridView. Grouping can be done on existing properties of the underlying data or with a custom value function. The displayed data can be altered through the exposed Display event.
Grouped rows can be quickly selected by double clicking the group header, and the rows can be collapsed and expanded by the user.

Usage:
3 simple steps
- Add the component to the designer or create it in runtime
- Set its DataGridView property to any existing databound DataGridView
-In runtime set the GroupOn property or call any of the SetGroupOn methods to start grouping

Other settings include
-the sorting of the groups (asc,desc or none, using the lists original sources order as leading)
-if the count of rows has to be shown (the shown information can be altered by catching the Display event)
-if the property name on which is grouped has to be shown (can also be altered by the Display event)
-besides the options above, the shown group value can also be altered in the Display event.

Background:
For a while now I was facing a request to add grouping to an overview in a DataGridView. And as you may have noticed: there is no grouping functionality in the default System.Windows.Forms.DataGridView.
Now there are ways of course, by adding DataGridViewRows manually and creating the groups by adding rows, but that would screw up the underlying data binding and automatic buffering/formatting/filtering/sorting, etc. Wanted to keep the bound functionality intact, but still create group rows. The solution in itself is simply to create a wrapper source that includes those rows and the grouped rows underneath and asign that to the grid, leaving the original source unaltered, and override the grouping rows painting/editing. A theory simple enough in itself, of course the implementation was a bit more work, but still less difficult than expected.
The grouping source was created easily enough, especially with the great functionality of Linq. The trick was in seperating what the grid saw from the underlying functionality. By inheriting from BindingSource all tools were available for that job. The DataSource and DataMember properties are set by the original values of the same properties in the Grid, therefor exposing the proper 'Columns'. All adding and removing had to be done in the underlying datagrid source, so those values were overridden.
The DataGridViewGrouper component itself is assigned to a grid and the Source of the grid itself is set to the grouped source. When a group row has to be painted, it is handled by the component, the other rows follow the default behaviour. Editing for a grouprow is simply cancelled. If the original source is a BindingSource, the source's positioning is synchronized.
Note that the index of the datagridview row won't be the same as the index in the original source, so you shouldn't be getting an object out of the original source directly with the row index. Then again, you should never do that anyway ;)  Use the Grid.Rows[position].DataBoundItem property instead.

Source Code

TODO:
* Now the component synchronizes navigation if the source is another BindingSource. Will look later to synchronize with any CurrencyManager.
* Adding code comments :p

posted on Friday, December 19, 2008 6:56 AM

Feedback

# re: DataGridViewGrouper SourceCode 12/19/2008 6:58 AM HotDog's Blog


# re: Grouping a datagridview: the DataGridViewGrouper component 1/24/2009 4:58 AM Mr. Donut
Hi HotDog,

Thanks. Excellent Post.

Pls post the DataGridViewGrouper component (.net 2.0 compatible).

# re: Grouping a datagridview: the DataGridViewGrouper component 2/7/2009 2:27 PM Michael
I second the 2.0 Compatible would be great.

# re: Grouping a datagridview: the DataGridViewGrouper component 2/10/2009 10:33 PM Hotdog
Hi guys,

thanks for the feedback! As per request, the code is now 2.0 compatible. However please see the 'new' note added in the post about the newer syntax (Visual Studio and not framework dependant). Hope the syntax won't pose a problem.

cheers,
Robert

# re: Grouping a datagridview: the DataGridViewGrouper component 5/24/2009 10:32 PM Avneesh
Good control

Post Feedback

Title:
Name:
Url:
Comments: 
Protected by Clearscreen.SharpHIPEnter the code you see: