Welcome to MSDN Blogs Sign in | Join | Help
Customizing the DataGridView to support expanding/collapsing (ala TreeGridView)

One of the first things that I wanted to customize with the DataGridView is to make it support hierarchical data

If you read my first blog post you'll find out that I'm not a developer (anymore). Even though I'm not a developer I still like to take features and customize them to do something really cool. As far as the DataGridView goes, customizing it to support hierarchical data is a much larger task since the structure of the DGV doesn't lend itself to having different column sets, so, I decided I'd settled for a tree like structure.

Think of a TreeView combined with a ListView and that is basically what I wanted to go with.

NOTE: This code is not supported by Microsoft and is provided "as-is". This code it not meant to show "best practices", but just showing a concept.

NOTE: This control is written to require Visual Styles to be enabled on your computer. You'll need to modify it if you want to run the TreeGridView without visual styles.

Code: http://www.windowsforms.net/blogs/markrideout/treegridview.zip

Here is a picture:

Anyway. The basic part of creating a DataGridView that can expand and collapse is to dynamically add and remove rows. That was the easy part. To make this really usable and extendable, I decided to add a lot code and make this easier to use. Here are some details:

Design

I wanted to ensure that the design of the TreeGridView supported normal TreeView type properties and features, so creating necessary classes to create the “tree view” experience wa necessary (see object model for more details).

Custom Painting – Painting an image in a cell is easy, but ensuring that the text from the DataGridViewTextBoxCell didn’t overlap the image took a bit of work. Using the Padding feature of the DataGridViewCellStyle, I add padding to the left side of the cell to account for the text and the indentation. This padding affects the painting and behavior of the text box cell, so editing a text cell correctly positions the editing control.

Siting/Unsiting a node – Since I don’t want to set padding and styling except when a node is actually displayed. When the node is displayed or in the grid, it is sited. When the node is sited I set all the necessary properties.

Unbound – Since expanding and collapsing is based upon dynamically adding and removing rows from the grid, I decided that unbound mode would be the best way to go with this. I’ve hidden the “databinding” properties and the virtual mode property since this doesn’t support those features.

Edit Mode – One thing that I had to deal with is that double-clicking a cell enters edit mode. This double-click occurs regardless of the padding, so double-click on the +\- symbol causes the control to enter edit mode. Edit also enters if you single click on a cell that already has focus. So, to deal with this I turn edit mode to be enabled only through programmatic means. I have code to handle the F2 key to enter edit mode. There are other ways to solve this, but I went with the F2 approach.

Object model structure

TreeGridNode - Just like a tree view, I wanted to have the concept of a node. I made the nodes class derive from a DataGridViewRow since a node in the list is the same as a row, just with a bit more info.

Here are some properties:

Nodes – Again, like the treeview, a node has children, so there is a Nodes property that returns child nodes. One of the challenges in coding this is to know when a node is actually a row or when it is just a node. A node is a row when it is in the grid, otherwise it is just a node.

IsSited – A node is “sited” when it is contained in the grid as a row. The Sited property is true in this case. There are a set of protected virtual methods on the TreeGridView class (SiteNode and UnSiteNode).

ImageIndex – Image index for the node’s image. Only used when an ImageList is associated with the TreeGridView.

Image – Image associated with the node. Sets or gets the image. When an ImageList is associated with the TreeGridView and an ImageIndex is set then this returns an image from the ImageList. You can set the Image property to an image if you aren’t using an ImageList.

Cells – Returns the cells for the given node. This wasn’t easy to do since accessing the cells for a node (or row) when the node isn’t sited. Using the DataGridView’s CreateCells method I can get the correct cells collection when the node isn’t in the grid.

TreeGridCell/Column – This is a special DataGridView cell that derives from the DataGridViewTextBoxCell. The main thing that this custom cell class does is to customize the cell drawing to make it look like a tree node. That means that it draws the node’s image and the +/- icons and the tree lines. The custom cell also is where a node detects when you click the mouse to expand or collapse a node. NOTE: A lot more work can be done to correctly detect that the mouse is directly over the +/- image. Right now I’m not doing that.

TreeGridView – This class derives from the DataGridView control. Many things are done in this class. Nodes are sited/unsited in the grid as actual rows. Somce DataGridView Properties are hidden since they do not apply.

Here are some properties:

VirtualNodes – One of the common things done with a normal TreeView is to dynamically add child nodes when the user is expanding the parent. With the normal TreeView usres add temp child nodes to get the + sign and support expanding, then remove the temp node later. With the VirtualNodes property, the TreeGridView always displays a + sign next to a node, even if the node doesn’t have any children. Then, by handling the Expanding event you can dynamically add child nodes.

ImageList – ImageList associated with the TreeGridView

Nodes – Identifies the root nodes.

ShowLines – Determines if the TreeGridView shows lines between nodes.

CurrentNode – Identifies the node that has focus.

Here are some events:

Expanding – Again, like the treeview, this event occurs before a node is starting to expand. You can add nodes in this event to fill in more details of a child node collection. When the VirtualNodes property is true, the TreeGridView will display the node with a + sign next to it even when it doesn’t have any children. Handling the Expanding event is where you would dynamically add new child nodes.

Expanded – After a node is expanded.

Collapsing – Before a node is being collapsed

Collapsed – After a node has been collapsed.

I’ve included a simple test app that creates a news group reader looking list that supports expanding and collapsing.

Let me know what you think and how you've used this in your project!

-mark

Posted: Sunday, January 08, 2006 6:44 PM by Mark Rideout [msft]

Comments

Paul said:

Just had a quick look. Its excellent. I was looking for something like this just today. A God send.

If you you feel the urge to make another control then something really missing in .NET 2.0 is a visual studio like docking manager. Or at the very least dragging toolbars in to floating windows.

Anyway on your TreeGridView, ill have a bit more of a play later but I think it will be very useful.
# January 9, 2006 1:04 AM

amitchat said:

quite awesome! Although I haven't tried out my own app, looking at the sample, it looks quite simple to use.

are there any plans to introduce a treegrid control in the next release of winforms?

-amitchat
# January 9, 2006 5:43 AM

Kevin Dente said:

Nice. Hierchical grids (or multi-column trees, depending on how you look at it) are really useful UI elements. It's frustrating that MS never provides one, forcing us to use 3rd party controls. This one looks promising.
# January 9, 2006 4:52 PM

ZAW said:

Thanks for your sharing.It is quite good.
Ah.. I got errors and I can't compile and reuse.
My VS version is professional version.Framework version is 2.0.50727
Can you help me?
regards
Zaw
# January 9, 2006 11:57 PM

Joo Lee said:

Mark - thanks for the great work. I think that in order to truly leverage the power of the datagridview in a hierarchical structure, we would need to incorporate more of the functions of both the DataGridView and the TreeView into your control, namely editable databound fields and restructuring/reordering of the nodes themselves. Such a control would be immensely effective in complex hierarchical data operations, such as structuring a Bill of Materials or orders/invoices. It's a great start though!
# January 10, 2006 2:52 PM

Ankur Gurha said:

To be honest, i just started looking to build a similar functionality today in one of our projects and here u go such a brilliant tip. Would let u updated how well did i manage.

Cheers!!
A...
# January 13, 2006 8:19 AM

zmt said:

i got errors
# January 13, 2006 11:23 PM

Jim Peterson said:

Wow, this looks great! I used it in an MP3 Jukebox app where I needed to display all the songs of a particular artist. Thanks a lot!
# January 17, 2006 6:09 PM

ale said:

Very nice and usefull!
# January 20, 2006 7:06 AM

Martin said:

Great works, thanks for sharing!
# February 1, 2006 8:34 AM

Jithesh said:



DID this Support DRAG & DROP
# February 1, 2006 1:29 PM

Fil said:

Great work! Thanks! You might want to add the following to the TreeGridCell.Paint event on line 218 to draw the lines in thick rows (that have the wrap property set to 'true'). if (node.HasChildren && node.IsExpanded) { graphics.DrawLine(linePen, (glyphRect.X + 4) + INDENT_WIDTH, cellBounds.Top + cellBounds.Height / 2, (glyphRect.X + 4) + INDENT_WIDTH, cellBounds.Bottom); }
# February 1, 2006 5:18 PM

うなまな Blog said:

TreeGridView
# February 1, 2006 7:32 PM

Logan said:

I want to move focus to next cell. I am using DataGridView control for DataEntry. So, When user done with editing particular cell and press enter, focus should go on to the next cell (not next row). How could I do this? please help me.. I am looking for this from last 10 days. Not got the solution yet. My email id is: logan@fissionvector.com
# February 8, 2006 12:55 AM

Shobh99 said:

Thanks a lot for the code.

I could include and utilize it by replacing TreeView control with this.

It was very useful for me.
# February 8, 2006 2:05 AM

SR said:

Looks wery good, but can I set focus to a special row? The "SelectedRows"is ReadOnly...
# February 10, 2006 9:48 AM

Mike said:

This control is very cool. Exactly what I was looking for. My only question is: I want two node columns, but I can't figure out how to reference the second columns nodes.
# February 13, 2006 11:12 PM

Srini said:

This is a really nice way of "combining" a tree and a grid. Thanks for sharing the code.

I have a question about doing this differently. Earlier, I tried to do the same thing with the earlier .NET 1.0. Instead of painting a tree structure over cells, I tried to create a composite component with a TreeView and a DataGrid on the same control, separated by a splitter. When the tree was expanded/collapsed, the DataTable associated with it was set to be altered.

It worked except for one pesky problem that I simply could not get rid of. The tree nodes and the grid rows never quite aligned. If one could manage that, one could achieve the same effect as you did with lesser coding, it seems. Do you know of any way to do this? Thanks, and thanks again for your code.
# February 14, 2006 4:11 AM

romz said:

how to bind using dataset?
# February 22, 2006 5:54 AM

harlequin said:

Hi, I really love the treegridview, but now i need to reorder nodes in it. (swap two nodes on the same level) I'd like to do this, without rebuliding the whole nodeset under the parent. Can you give me some ideas how can i make it? thankyou
# February 23, 2006 8:21 AM

Henry Vu said:

Your treegridview have bug if VisualStyle is not enabled on your windows.
Can you fix it? I really need your code. Thanks your code
# February 26, 2006 9:03 PM

Dwight Kulkarni said:

Hi Mark,

I am trying to get hold of you for a slightly different problem. I need to understand the DataGridView event model more deeply but I am having trouble locating information I need. Much of the information out there is for bound data sources and deals a lot with the appearance and display of the view. I am working with an unbound grid that requires extensive event customization. I have developed a custom GridCell and have defined some events for that GridCell, but I am not sure how to listen for these at the DataGridView level. How do I register listeners for custom events? Can you reference any good links .. I have combed through a lot of articles on MSDN and else where but so far no luck.
# February 27, 2006 10:00 AM

azuro (at) gawab (dot) com said:

Niiice control.

Consider enablin' databindin'.

One of other cons - not workin' w/o VisualStyles. Here is the fixxx:

in "TreeGridView.cs" delete the followin' two lines:

------8<------
internal VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
internal VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
------8<------

in "TreeGridCell.cs" find the line "if (node.HasChildren || node._grid.VirtualNodes)" and change it so that it looks like that:

------8<------
           if (node.HasChildren || node._grid.VirtualNodes)
           {
               // Ensure that visual styles are supported.
               if (Application.RenderWithVisualStyles)
               {
                   VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
                   VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);

                   // Paint node glyphs
                   if (node.IsExpanded)
                       //node._grid.rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
                       rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
                   else
                       //node._grid.rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
                       rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
               }
               else
               {
                   int h = 8;
                   int w = 8;
                   int x = glyphRect.X;
                   int y = glyphRect.Y + (glyphRect.Height / 2) - 4;
                   //MessageBox.Show("x = " + x.ToString() + ", y= " + y.ToString());

                   graphics.DrawRectangle(new Pen(SystemBrushes.ControlDark), x, y, w, h);
                   graphics.FillRectangle(new SolidBrush(Color.White), x + 1, y + 1, w - 1, h - 1);
                   graphics.DrawLine(new Pen(new SolidBrush(Color.Black)), x + 2, y + 4, x + w - 2, y + 4);

                   if (!node.IsExpanded)
                       graphics.DrawLine(new Pen(new SolidBrush(Color.Black)), x + 4, y + 2, x + 4, y + h - 2);
               }
           }
------8<------

haha!
# March 18, 2006 5:19 AM

_JERKER_ said:

I really like the News Reader GUI look! EXACTLY what I want for my hierarchical task list application.

However, as the previous post, the only 'thing' that's missing is the data binding... But, the good thing is that its not that much work to make it happen...

I'm thinking of doing this myself, if it's not "too late" - someone else has done that already...?

Thanks!

# March 29, 2006 6:09 AM

Jerry Nixon said:

Beautiful. Move it to SourceForge (or somewhere)!
# April 4, 2006 5:50 PM

jk said:

This looks really promising, however, I am havng problems even on the smallest sample:
Put the grid control on a Form, added a column and on the FormLoad, called Nodes.Add("test"). I get the following:

Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'.

on line 264 of TreeGridNode.cs (in the cells_CollectionChanged function)

Surely, I am doing soethin wrong.... Ay pointers please
# April 7, 2006 5:57 PM

Tim Cartwright said:

Mark, I really like your control, but what I am trying to accomplish I am finding rather difficult with any of the grids at my disposal, nor am I able to find a clean solution. I am able to use the DataGridView and the C1FlexGrid, I am unable to purchase any others based upon budgetary constraints. I am hoping you can help with a suggestion or where a free control that can accomplish my needs.

The Issue:
I need to display a complex hierarchy of differentiating data in multiple stepped grids. Here is the hierarchy :

Order
----GRID:LineItem(s)
--------GRID:LineItem Price Assignment(s) (discounts, specials, etc.)
--------GRID:LineItem Option(s)
------------GRID:Option Price Assignment(s) (discounts, specials, etc.)

Each one of these grids has different columns, and data. I do not really want to use the standard - seperate grids to display the master - detail data. I would prefer if this was treed somehow.
# April 18, 2006 3:54 PM

staceyw said:

Nice.  Two questions:
1) How might one implement sorting columns?
2) Headers don't seem to "click" or show the thin orange bar on the bottom on hover.
# April 19, 2006 2:11 PM

John Bollwerk said:

Mark

A few years ago I wrote an application in VS2003 Managed C++ using a similar control called ContainerListView which is a combined TreeView and ListView control.  I am in the process of updating the application using VS2005 and CLR/C++ and am looking at your control as a replacement for the ContainerListView control.

I was able to add your control to my ToolBox after rebuilding the dll (got a .ctor error with the downloaded dll).  However, when I try to create a node using either the designer or in code I get the following error:

Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'

This occurs at line number 264 in TreeGridNode.cs.  The line is:

treeCell = (TreeGridCell)cell;

I don’t speak C# very well and am not sure how to fix the problem.  I suspect that because I’m writing in C++ this may just be the tip of a compiler iceberg.  Any thoughts or suggestions?

Thanks

John
john.bollwerk.ctr@scott.af.mil
# April 25, 2006 10:12 AM

Jason Ellenbogen said:

You Rock!!!  So great to have people that contribute like this.

Thanks!
# April 26, 2006 9:38 AM

Chad said:

I am doing something similar when I extend DataGridView, and the WinForms designer gives me the same errors that this project does ...

The variable 'treeGridNode6' is either undeclared or was never assigned.  


Could not find type 'AdvancedDataGridView.TreeGridNode'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built.  


Can anybody suggest a fix?  Thanks
# April 27, 2006 8:44 PM

Patrick said:

I've been enjoying the control, but I'm having trouble getting it to scale well. Having a node with anything more than 20 children quickly becomes unusable (50 nodes takes over 10 seconds to expand). It seems to come down to setting the this.Style.Padding on each cell, instead of using the default. Am I missing something or is creating a style for each cell really expensive?

Thanks.
# April 28, 2006 12:14 PM

vishala said:

Thanks for the great code Mark.
But i had question,when i try to add items more than 1000 items in the tree,it takes extremely long time to update.
Is there a way the efficiency could be improved.
# May 3, 2006 1:15 PM

erol said:

this is really cool.but adding databinding property would be perfect.if anybody had made this, please show the code:) i really need it.
# May 23, 2006 5:03 PM

eltonic40 said:

Thanks for the great code. How can i add in support for row template. I see from you code, you disabled it in the treegridview object. However, I'd like the ability to control the row height. where can i make the insertions?
# May 25, 2006 6:57 AM

Zoki Manas said:

it is a great code.....is there any way to put check boxes instead of text boxes....I need something like : check Parent node...check all child nodes....
# May 29, 2006 3:24 AM

Yuval Ararat said:

Hey Fil. your code. where does it go?
in line 218 there is an else.

all the rest
did any one added Databinding to this?
i see i am not the only one asking...
# June 7, 2006 12:27 PM

Zoki Manas said:

Is it posible to have grouped columns in the grid. expandable with (+) sign...or something like that..similar like having tree view on the left..i need master detail functionality where the columns are?
# June 14, 2006 9:21 AM

rape stories said:

Your article is prety nice. It's a pity that i didn't see it more later.
# June 20, 2006 4:57 AM

Kris Wragg said:

Just wondering if anyones looked into implementing sorting with this control? and if so how they managed it? Need to implement it for my control and unsure where to start...
# June 20, 2006 8:04 AM

Gontsov Evgeny said:

I need databinding, may be i make this.

Vary thanks for the this control !

Best regards to autor !
# June 26, 2006 10:06 AM

JorginhoPC said:

The tree is expanded.

how do I get the current node?

I need to get the values on the click or double click...
# August 1, 2006 11:18 AM

webcliff said:

Mark,

How can I toggle the highlighting on a row with every mouse click?
I tried to override SetSelectedRowCore with no luck.

# August 1, 2006 5:28 PM

Miselly said:

thanks for code.
but,i hope VB source
# August 19, 2006 9:31 PM

Pradeep said:

Can I have a check box column in this treeGridView control, so that user can select multiple items
If possible can u send me the code
# September 3, 2006 11:21 AM

Julia said:

Good work!
Can I have it in  2003 version?
Thanks.
# September 4, 2006 10:14 PM

amk said:

The Tag property of a TreeNodeCell does'nt work. I've added a new TreeNodeCell programmetically and set its Tag property to some integer and tried to get that it returns null
# September 7, 2006 2:38 AM

nrasinec said:

Hello,

I had a similar idea some time ago and here is the result: Hierarchical DataGridView. Component works in a similar way - instead of a node collection it uses data in System.Data.DataTable to represent hierarchically organized data.


Regards,
Rasinec Ninoslav
ApplicationAspect.com
# September 9, 2006 2:00 AM

Sima said:

Very nice. What about databinding, did anybody made it?
# September 16, 2006 12:35 PM

Eli said:

First of all, Great job.
I'm tring to implement sort, I've though about using the
level of a node and the SortCompare event (only values with the same level will be sorted), my question is, how can I get the node of a row from the RowIndex property?

thanks...
# September 26, 2006 4:10 AM

Lex said:

Hi,

Who solved the error :

Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'.

Thank you

# October 27, 2006 8:13 AM

Natarajan said:

Hi,

Is it possible to create a custom datagrid with the feature of expandable columns like expandable rows? Using that a user can expand and collapse the columns to edit the data.

I am searching this for a long time.

Please give me your valuable feedback.

Thanks,

Natraj

# November 7, 2006 5:20 AM

Baskar C.G said:

Looks Good. But is it compatable with Framework 1.1. I am using VS.NET 2003 and i am not able to add this control in my project. getting following error message.

"ExpandableGridView.dll not a Microsoft .NET module"

# November 8, 2006 1:02 AM

ramazan said:

hi. I want to ask question about code copyright? What does is mean?

Can I use in commercial application with microsoft visual c# 2005 express edition?

# November 14, 2006 10:55 AM

Jason said:

In order to fix the error that most people are receiving you have to goto the properties for the treegridview and then click on columns.  It automatically defaults to DataGridTextboxColumn for ColumnType.  You need to change this to TreeGridColumn.  Took me a minute to figure out as well.

# November 23, 2006 9:36 PM

Justified said:

For those who are encountering the following error:

Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'

I'm only dealing with text but I accidentally selected a Column Type of System.Windows.Forms.DataGridViewTextBoxColumn instead of AdvancedDataGridView.TreeGridColumn  once i changed it to TreeGridColumn, walla.

This fixed it for me.  I'm using this in a VB.Net Project.

Hope this helps

Justified

# November 28, 2006 7:54 AM

Tzippy said:

I wanted to use the control in windows 2000, without the XP Visual Styles, so I made some changes, based on another project I found here:

http://www.codeproject.com/cs/miscctrl/XPCollapsGroupBox.asp

The changes are:

In the TreeGridView.cs instead of the 2 rows:

internal VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);

//internal VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);

I have:

internal Graphics rOpen ;

internal Graphics rClosed ;

In the TreeGridCell.cs

Instead of :

// Paint node glyphs

               if (node.IsExpanded)

                    node._grid.rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));              

               else

                    node._grid.rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));

I have:

// Paint node glyphs

               if (node.IsExpanded)

               {

                   node._grid.rOpen = graphics;

                   node._grid.rOpen.DrawImage(Properties.Resources.minus, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));

               }

               else

               {

                   node._grid.rClosed = graphics;

                   node._grid.rClosed.DrawImage(Properties.Resources.plus, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));

               }

For the last code snippet I added 2 images to the project resources. The images could be found in the project I mentions its url in the beginning.

# December 18, 2006 9:47 PM

Vikaash said:

i added the ExpandableGridView.dll in my vbdot ent project, but i am not able to add the Refernce of C# classes required into my vb project. how to do it ?

# December 26, 2006 12:03 AM

BillB said:

I've mananged to get a datagridview working very well with grouping as well as expanding and collapsing icons in the grid.

The grouping has a category as the parent and descriptions... price... etc... as children with an item count in the Parent.

Looks like this sort of in the DataGridView:

Some Category (Plus Item Count)

            Descritpion        Price        Sold

Some Category #2 (Plus Item Count)

            Descritpion        Price        Sold

etc...

It also has all the trimings with row delete... notes addition from a currentcell doubleclick which i'd be happy to share if anyone is interested.

I have been trying to implement a DragDrop and having major trouble maintaining the above group when I move the rows in the DataGridView. I need to keep the Parent/Children relationship when the rows are moved in the DataGridView.

Has anyone done this before that can offer the right way to go about solving the above? Have sample code to illustrate???

Any help would be greatly appreciated... Thank you in advance.

Thanks,

BillB

# January 8, 2007 3:53 AM

Ray said:

I got an error:

Object reference not set to an instance of an object.

Site: Void UnSiteNode

       TreeGridView.UnSiteNode(TreeGridNode node)

       TreeGridView.Dispose(Boolean disposing)

# January 19, 2007 5:08 AM

Juan Azabache said:

I get a Error, using: Remove() (for sub Items)

After used the method "Remove", I can not use the Expand() method.

# February 1, 2007 11:36 AM

Brian H. Madsen said:

hey, using you as a basis i just created a DataGridViewTextboxCell which is a tree in itself in a windows form - rather than the entire grid.

thanks for the tips!!

# February 1, 2007 9:41 PM

Chintan said:

Hi Mark,

     could you please tell me why did you choose to dyanmically insert/Remove a row for expand/collpase instead of setting it's visible property to true/false.

Regards,

Chintan

# February 4, 2007 6:11 AM

Mark Rideout [msft] said:

Chintan -- I wanted to expose the child nodes collection for a node and the expanding/collapsing events to allow users to dynamically add/remove nodes. As a result of this my code would dynamically add/remove rows. I would have had to know if the row was in the grid first to make the row invisible. While easily done I didn't want the rows in the grid to affect any other aspect of the grid.

For example, RowCount is affected with visible=false rows. In addition, a large number of rows in the grid even if they are visible=false affects the grid's performance in unbound mode, so I didn't want to have that impact.

Hope this helps,

-mark

# February 6, 2007 2:58 PM

Focus to Next Cell said:

I want to move focus to next cell. I am using DataGridView control for DataEntry. So, When user done with editing particular cell and press enter, focus should go on to the next cell (not next row). How could I do this? please help me.. I am looking for this from last 10 days. Not got the solution yet. My email id : vdp_30@yahoo.com

# February 22, 2007 11:32 PM

... said:

Great site! Good luck to it's owner!

# March 19, 2007 10:04 PM

Isha said:

Really a wonderful job.

One Query.Can i add images in the third column.If yes then how

# April 12, 2007 1:24 AM

Agus Sanjaya said:

Hi Mark, I have downloaded your TreeGridView, but when I ran it. it gave errors. Also when I tried to open the Simple Test App, the visual studio said that there were more than 2 errors, it closed immediately. Did I miss something?

# April 25, 2007 4:55 AM

david said:

Thank you very much for this code! I needed it in VB.NET, so now will i try to rewrite it in VB. Although, i believe that wouldn't be a problem.

# April 26, 2007 2:46 AM

MDT said:

I am curious if anyone is trying to use this on a .NET form that is accessed VIA Interop. I am asking because i am running into some threading issues and was maybe looking for some help.

Thanks!

# May 2, 2007 8:46 AM

bob said:

Hi,mark.the control is very well to use.but i have a question.when i insert a row, it always at the last row.

at TreeGridNode.cs , the InsertChildNode function, there is  a note: //TODO: do we need to use index parameter?

how can i use it?thanks

# May 9, 2007 11:54 PM

Shashank said:

Fundoo code!!

You showed me the way to it.

But i needed to include it into my project that is on VS2003 and 1.1 framework.

Do you have any links or suggestion how to go about it.

I am facing problem including the files that you wrote because framework 1.1 doesnot support few of the assemplies that are used here.

,

Shashank

# May 11, 2007 2:45 PM

CH said:

Trying to get this to work in Compact Framework.  Initially, I've had no success.  Any ideas?

Thanks.

CH

# May 16, 2007 11:55 AM

Faisal said:

Hi All,

DataGridView - Please Help

I want to move focus to next cell in DataGridView control, as when user done with editing particular cell and press enter, focus should go on to the next cell (not next row).

How could I do this?

please help me..

my email is

faisalbilwani@hotmail.com

# May 17, 2007 4:29 AM

Khaleed said:

hi,

i love the idea of treegridview has been implemented here. I wanted to know if u have this treegridview sample example in asp.net using C#. If u donot then could u post some url where i could get sample example of treegridview in asp.net

Thanks...

# May 17, 2007 8:43 PM

Mostafa Iqbal said:

Hi, Mark. This is a very nice control that you have developed. But can you tell me how can i use your control in ASP.net 2.0. If this control can not be used in ASP.net,can you please tell where can i find the same with ASP.net support.

# May 22, 2007 1:48 AM

Hamid said:

Hi, thanks for your excellent effort for enabling the gridview for such a great functionality.

# May 28, 2007 2:15 AM

Karthik said:

Hi mark,

This is very useful for me and my team.

great work!

Thanks for sharing this code and open my eye to view such property in Data Grid View.

Karthik.C

# June 14, 2007 3:47 AM

Inserting new rows said:

I also noticed the problem that when inserting a new node, it is always the last one. Does anyoone have a solution?

# June 22, 2007 4:06 PM

Ehab Hosny said:

Hi Mark,

It is really great control but i have 2 questions or comments.

1- Why is the row index have different values when it is expanded and collapsed in other words the collapsed rows (Unvisible) is not counted in the TreeGridView control and this may cause some troubles.

2- In the TreeView control there were 2 properties IsExpanded and IsCollapsed to allow developere to know if a certain node is expaneded or collapsed and there were 2 function Expand() and Collapse() to allow developer to expand and collapse nodes but in your control you omitted the 2 properties and the 2 functions are just getting the node state whether it is expaneded or not and thus I don't know how I can force the control to Expand and Collapse the Node.

I wish to have response for these 2 questions as soon as possible

Thnx alot

# July 11, 2007 11:59 AM

dgcl said:

Hi, this just great!

I'm new in VB.Net, and I'm wondering if it's possible to use it in VB.Net,  if it's so, How could I use it?

Thank's a lot!

# July 13, 2007 1:45 PM

Aarthi said:

Did anyone figure out a way to do databinding? Please share your ideas.

# July 13, 2007 4:54 PM

kriz said:

Hi

I'd like not to use images, i removed treeGridView1.ImageList fully but still have white squares after them, how to get rid of it?

# July 16, 2007 8:20 AM

Ehab Hosny said:

I want to know how i can expand and collapse in code in other words what functions can do it, in normal tree view i can do it using Expand() and Collapse() functions but here they have another behavior, so can anyone help?

# July 24, 2007 4:25 AM

Realite said:

Woowww... It's a good and useful component. Thank's a lot...

# August 8, 2007 4:20 AM

tsueng chen said:

Hi,

  Do you have vb version? It looks great. That is exactly what I want.

tsueng@yahoo.com

# August 10, 2007 3:09 PM

Poonam said:

Hi,

Can u pls tell me that how can i change code so that my TreeGridView control enable Drag and Drop facility??

I Mean to say that in typical TreeView , we can bind ItemDrag event and this Event further make a call to DoDragDrop() function.

Here How can i call DoDragDrop function?

Thanks

# September 10, 2007 5:37 AM

Karl said:

Hi Mark,

at the first look this control looked very well, but I encountred some problems.

First you are using virtualstyles (XP) which are by default not available under W2003 Server where we are developing. This was easy to resolve using two Images and draw the images when Styles are disabled.

But a nothe r thing I couldn't fix.

I made a example with 6 levels and 2260 rows. Implementing a method ExpandAll calling ExpandNode recursivly.

ExpandAll takes 532 Seconds to do its work, thats abou 9 Minutes.

Any idea how to Implement ExpandAll and CollapseAll which is faster ??? Must be a lot of faster !!

# September 12, 2007 6:50 AM

Brad said:

How do I get the currently selected Node?

# September 13, 2007 4:02 PM

jasonlaw said:

How can I set focus to a special row?

Please help.....

# September 21, 2007 3:09 AM

Jay R. Wren said:

I can't let you know how I have used this in my project because directly using the code would be a violation of your and microsoft's copyright.

Could you please attach a license to this code?

Thanks

# October 2, 2007 12:53 PM

Bill Davis said:

great work! But, I'm curious why you didn't just use a treeview/listview combination (like Windows Explorer)?

# October 8, 2007 11:42 AM

Alex Efimov said:

Hi, Mark. I've developed custom programming language for our ERP-system and used your control to make a Visual Studio-like debbugger. I'm really lucky to find your blog, your control works perfect. I have found many interesting things in sources ;)

Thanks.  ;)

# October 10, 2007 3:59 AM

Jay R. Wren said:

"Postings are provided "As Is" with no warranties and confer no rights."

See the notice on the side of this blog.

Anyone downloading and using this example in production code is redistributing copyrighted work. Please ask the original author for a more free license.

# October 15, 2007 10:01 AM

Yogesh said:

Hi

I want Column where in that column cells i can put text as well as image on right corner of cell

Thanks

# November 13, 2007 7:31 AM

Yogesh Nayak said:

Hi

I want Column where in that column cells i can put text as well as image on right corner of cell

Thanks

# November 13, 2007 7:31 AM

Marlou said:

I was trying the code to VB..but I got problem on some functions

Does Anyone have a VB version of this code.

Please Post Thanks.

# November 13, 2007 9:43 AM

Nal.S said:

Hey Mark,

This doesnt work with Windows 2000.

Throws a exception at line: 42 of file: TreeGridView.cs

and says "Visual Styles-related operation resulted in an error because no visual style is currently active."

This happens both when running New Reader Look and also when running "Simple Test App"

Any suggestions on how to correct this ? feel free to mail me...

Just wondering...

Nal

nsnsns(at)gmail(dot)com

# November 13, 2007 12:17 PM

civa_i_shone said:

awesome dude very impressed with this stuff

helped us so much

n1

# November 13, 2007 1:11 PM

Josh Hunt said:

Hey Mark, Josh from missouri.  I know this blog isn't for personal stuff, but I don't have your other contact info anymore.  I hope you're doing well.  Contact back if you like.  joshhurlahee@hotmail.com

# November 23, 2007 1:05 PM

rama charan said:

Hi Mark,

 good work ...

     A small suggestion from my side .I think it would be great if you could try to develop it as a  usercontrol for   web application.

# December 4, 2007 3:46 AM

Anton said:

Man, you are a star. Just what I've been looking for! Thanks a million.

# December 4, 2007 9:53 AM

yannick said:

Hi,

Im trying to include your code in my application. The only thing Ive modified is to remove the attachemnt column to reduce the number of columns to 3. However, each time I want to add a node, The Cells.Count always return 0 instead of 3. Im developing my app under Linux.

Any idea of what might go wrong?

Thank you

# December 7, 2007 6:39 PM

Spoook said:

Hi,

it is a very nice code, and it's something I was looking for.

But it has some bad sides.

one is this;

code:

AdvancedDataGridView.TreeGridColumn treeColumn = new AdvancedDataGridView.TreeGridColumn();

           treeGridView1.Columns.Add(treeColumn);  

           treeGridView1.Columns.Add("first", "first");

           treeGridView1.Columns.Add("second", "second");

           AdvancedDataGridView.TreeGridNode node = new AdvancedDataGridView.TreeGridNode();

           AdvancedDataGridView.TreeGridNode node2 = treeGridView1.Nodes.Add("x", "x", "xx");

           treeGridView1.Nodes.Add(node);

           node.SetValues("1", "A", "B");

           node = new AdvancedDataGridView.TreeGridNode();                        

           node.SetValues("3", "aaA", "bbB"); //not visible

           node2.Nodes.Add(node);

           node.Nodes.Add("y", "y", "y");

           node = new AdvancedDataGridView.TreeGridNode();            

           treeGridView1.Nodes.Add(node);

           node.SetValues("4", "aaaA", "bbbB");

end code

a very simple code, but the node marked not visible will be empty in the grid....strange...

also strange that if you fill the node with data before adding it to the treeGridView (or another node) it will be still empty.

I am trying to use this for my monitoring app.

I'll be back with my results

# January 8, 2008 9:48 AM

Billy W. said:

helle all out there,

that's a great thing. Unfortunately it doesn't work for me (VS 2003).

Has anybody convertet it to VB ? I would like to have it very hard....

# January 13, 2008 9:24 AM

Functional Illiterate said:

I suppose I'm pretty late to the party.  I am, however, interested in taking a look at this code as a starting point for a slightly different extension.  However, the Link up to no longer works... Does anybody have this zip laying around.  If let me know where I can find it.

fi

# January 30, 2008 10:49 PM

Kornel said:

Hi, i tried to get the source, but, its not there anymore..

am i too late?

# February 2, 2008 9:03 AM

Juliette said:

He everybody.

As I can see there are a lot of you, who had a Databinding issue.

Does anyone here have a solution for that?

We are working on binding the treegridview to a Datatable, dataset or an XML file, but we can not figure out, how to bind any of them to the treegridview!

I hope anyone can help!

By the way, it is a greate control.

# February 20, 2008 5:52 AM

mscirri said:

Has anyone figured how to get DefaultCellStyle.Alignment to work for the columns? No matter what I set it to it aligns the contents to the left.

# March 12, 2008 10:16 AM

Matt Hanson said:

I, as well, was curious if anyone has successfully ported the source code to VB.NET? I am using the express edition of Visual Basic, so having different parts of my application in different languages does not make the most sense.

Anyone?

# March 17, 2008 10:22 PM

ManiX said:

Hi Mark,

Thanks for the nice post. I am new to C# as well as DataGridView. Could you please help me in extending DataGridView that contains another DataGridView in one of it's columns. I don't want the user of my application to edit data. Kindly help me to solve my problem.

Thanks and Regards,

ManiX

mail2manix [at] gmail [dot] com

# April 1, 2008 1:25 AM

Murad said:

HI

I am insert TreeGridView in my solution

When I try to put on the my form a component TreeGridView, that I receive error.

---------------------------

Microsoft Visual Studio

---------------------------

Failed to create component 'TreeGridView'.  The error message follows:

'System.InvalidOperationException: Visual Styles-related operation resulted in an error because no visual style is currently active.

  at System.Windows.Forms.VisualStyles.VisualStyleRenderer.IsCombinationDefined(String className, Int32 part)

  at System.Windows.Forms.VisualStyles.VisualStyleRenderer..ctor(String className, Int32 part, Int32 state)

  at System.Windows.Forms.VisualStyles.VisualStyleRenderer..ctor(VisualStyleElement element)

  at AdvancedDataGridView.TreeGridView..ctor() in D:\VSS\Отчет по рискам\Исходники\C#\RiskReport\TreeGridView\TreeGridView.cs:line 42'

---------------------------

ОК  

---------------------------

With what it can be connected?

# April 2, 2008 9:22 AM

commenter said:

Great control. But I would like to be able to host streaming videos within cells of the control. Can you please implement that?

.

.

.

(just kidding).

# April 14, 2008 11:12 AM

imran said:

Can we display checkboxes in tree ??? if yes then how plz reply thanks

imran saeed

email: imransaeed@my.web.pk

# April 18, 2008 1:17 AM

Yagnesh said:

Hi Mark,

This is very useful.

How do we do for DataTable/DataView as DataSource?

Something like :

OrderNumber:0001

   ItemNumber            ItemQty

OrderNumber:0002

   ItemNumber            ItemQty

# May 12, 2008 1:50 AM

waspy59 said:

hello,

it's a very nice code. do you have it for vb.net? C# is unknow for me....

thanks,

# May 15, 2008 5:20 PM

Guilherme Melo said:

Hey, I've written some code to support DataBinding. It works just fine.

However, the code is very application specific, since the data source doesn't have column information and to bind everything to "textbox" would not be interesting.

What do I do: I wrapped the component within a UserControl then do statically create my own columns according to my application needs and then do a custom databind method.

Here is the one I did inside the user control:

[DefaultValue ( "" )]

[RefreshProperties ( RefreshProperties.Repaint )]

[AttributeProvider ( typeof ( IListSource ) )]

public DataTable DataSource

{

   get

   {

       return ds;

   }

   set

   {

       ds = value;

       foreach ( DataRow dr in ds.Rows )

       {

           // Retrieve columns

           object [] p = new object [ ds.Columns.Count ];

           for ( int i = 0; i < ds.Columns.Count; i++ )

           {

               p [ i ] = dr [ i ].ToString ();

           }

           // Inserts a row

           treeGridView1.Nodes.Add ( p );

       }

   }

}

Don't forget to remove the declarations from the TreeGridView class to get rid of the exceptions and let the databind work :)

# May 16, 2008 1:27 PM

Vidya K.A said:

Hi Mark , Great Job ... i found it amazing.

I was trying to use listview instead of Treeview.

It fetched some ideas to me.

Thanks a lot..

# May 22, 2008 1:17 AM

Saurabh057@gmail.com said:

I need to incorporate drag drop functionality in the TreeGridView.In this functionality one should be able to drag drop from TreeView as well as within the TreeGridView.

Could any one please help me out?

Thank you

# June 6, 2008 3:25 AM

Greg Shebert said:

Given a row index, how can I find the node associated with what is displayed in that row?

It does not appear to be trivial unless I am missing something obvious... Is there a helper function for this?

Thanks

-G

# June 12, 2008 10:09 AM

Marc G. said:

Brilliant control! Thank you Mark!

# June 17, 2008 3:32 AM

Rupinder said:

Hi

I did the data binding successfully but i dnt know how to save that data in database like parent node's data separately and child node's data separately.

# June 24, 2008 7:16 AM

One more said:

Sort columns:

private void treeGridView1_CellClick(object sender, DataGridViewCellEventArgs e)

       {

           if (e.RowIndex < 0)

           {

               foreach(TreeGridNode node in this.treeGridView1 .Nodes)

               {

                   node.Collapse();

               }

               ListSortDirection direction = new ListSortDirection();

               if (this.treeGridView1.SortOrder == SortOrder .Ascending )

                   direction = ListSortDirection.Descending ;

               else direction = ListSortDirection .Ascending ;

               this.treeGridView1.Sort(this.treeGridView1.Columns[e.ColumnIndex ], direction);

           }

       }

# June 29, 2008 8:28 PM

Martin said:

Has anyone found a solution to the slow recursive expanding node problem yet?

# July 9, 2008 6:28 PM

Marco Aurélio Gerônimo said:

Hi Mister....

this grid.. is very good... thanks!!!

....

Marco

# August 12, 2008 8:23 PM

d4dennis said:

Don't know what to say. Please accept my millions thanks.

# August 14, 2008 1:54 AM

JM said:

Hello, nice control.

thanks!!!

JM

www.pronexo.com

# August 15, 2008 8:18 AM

Peter said:

I am trying to use your control in my application and in process of evaluating that control found that when using about 200 subnodes in root node, the time to expand that node is about 6 sec, but if I will try to expand similiar second node with also 200 subnodes and not collapsing first one, it will take almost double time, when trying to expand third node with 200 subnodes, it will take almost tripple time and so on. Is it something with control or with the way I am trying to add nodes.

Any response will be appriciated.

Thanks,

Peter

# August 20, 2008 3:06 PM

Vadim Koystinen said:

to expand and collapse all nodes

add this code to TreeGridView class

[Description("Expands all nodes")]

public void ExpandAll()

       {

           foreach (TreeGridNode node in this.Nodes)

           {

               expandNode(node);

           }

       }

private void expandNode(TreeGridNode node)

       {

           if (node.Nodes.Count > 0)

           {

               node.Expand();

               foreach (TreeGridNode subNode in node.Nodes)

               {

                   expandNode(subNode);

               }                    

           }

       }

[Description("Collapse all nodes")]

public void CollapseAll()

       {

           foreach (TreeGridNode node in this.Nodes)

           {

               collapseNode(node);

           }

       }

       private void collapseNode(TreeGridNode node)

       {

           if (node.Nodes.Count > 0)

           {                

               foreach (TreeGridNode subNode in node.Nodes)

               {

                   collapseNode(subNode);

               }

               node.Collapse();

           }

       }

ps

recursion rocks

# September 1, 2008 4:50 PM

Marcelo Fabiano said:

This looks really promising, however, I am havng problems even on the smallest sample:

Put the grid control on a Form, added a column and on the FormLoad, called Nodes.Add("test"). I get the following:

Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'.

on line 264 of TreeGridNode.cs (in the cells_CollectionChanged function)

Surely, I am doing soethin wrong.... Ay pointers please

# September 4, 2008 10:38 AM

Gary said:

Plz someone convert it to vb version please....

# September 8, 2008 12:12 AM

Andrej Vilinski said:

good idea for Expand/CollapseAll, but i would place the collapseNode method into TreeGridNode:

TreeGridView.cs:

/// <summary>

/// Expands all nodes.

/// </summary>

[Description("Expands all nodes")]

public void ExpandAll()

{

foreach (TreeGridNode node in Nodes)

node.ExpandAll();

}

/// <summary>

/// Collapses all nodes.

/// </summary>

[Description("Collapses all nodes")]

public void CollapseAll()

{

foreach (TreeGridNode node in Nodes)

node.CollapseAll();

}

and TreeGridNode.cs:

/// <summary>

/// Collapses all nodes and all child nodes recursively.

/// </summary>

public void CollapseAll()

{

if (Nodes.Count > 0)

{

foreach (TreeGridNode subNode in Nodes)

subNode.CollapseAll();

Collapse();

}

}

/// <summary>

/// Expands this node and all child nodes recursively.

/// </summary>

public void ExpandAll()

{

if (Nodes.Count > 0)

{

Expand();

foreach (TreeGridNode subNode in Nodes)

subNode.ExpandAll();

}

}

# September 9, 2008 3:46 AM

Jiong said:

Gary,

To use this with VB.NET, just compile it into a class library (dll) and add it as a reference to your project.

# September 16, 2008 3:20 PM

Jiong said:

Marcelo,

Try reading Spoook's post. Then, use that code.

# September 16, 2008 3:24 PM

Bch said:

How can we allow the user to add rows? or modify some row? ..

# October 24, 2008 5:51 AM

nerix said:

Hi,

To begin, thank you for this custom control.

I use it more and more to overcome the limitations and delays of the classical listview.

However, I meet a problem of memory usage.

I must show a treegridview with approximately 2000 rows, and 50 columns. When I create that rows for the first time, all is ok.

To win speed display, when I create rows, I make my columns invisible, and after the process of creation, I make my columns visible. It saves a lot of time to create/show the rows.

The problem comes when I want to refresh my informations list.

I delete all my rows, and I recreate them. The problem is that "Rows.Clear()" does not release memory. For each refresh, the process takes more time. And when I try to close the window control (after the first refresh), it freezes.

I tried some functions of control, without success !

Are you've encountered the problem ?

Can you help me ?

In advance thank you.

Eric

# October 28, 2008 9:34 AM

Jiong said:

Memory release is controlled by the .Net garbage collector. This was done so that you don't have to worry about memory leaks. And, from what I can tell, .Dispose() may be the closest thing you have to memory release, but it isn't really such a thing.

The freeze occurs when you've run out of memory and windows tries to swap with the hard drive. You can try listening for the heavy clicking on your disk. If you can hear it, you've found the problem. If you don't, I've not a clue. If you're running something on a thread, that may be holding you up.

# October 28, 2008 4:55 PM

Radu said:

@nerix

just try it for several times, to write and afterwards delete the contents of the grid and look at the task manager memory consumption. You will see that after several cycles the memory gets released. I use the following command:

treeGridView1.Nodes.Clear();

As I said, I tried it for 20 write/delete cycles with a grid consisting of 5000 nodes with 5 subnodes each and it seems to work. The bandwidth of memory consumption is about 200 Mb.

@all

Also, if acceptable, set

treeGridView1.Visible = false;

at the beginning of the loading process and at the end back to true. It seems indeed to speed up a lot the loading.

I also use a secondary thread to fetch the data and delegate periodically the writing to the ui thread to load it.

From the UI thread:

System.Threading.Thread t = new System.Threading.Thread(SqlReadData);

t.IsBackground = true;

t.Start();

The delegate:

private delegate void UpdateDelegate(string[] d);

In the background thread:

... fetch the data...

 string[] str = new string[5];

 str[0] = MyReader.GetString(0);

 str[1] = MyReader.GetString(1);

 str[2] = MyReader.GetString(2);

 str[3] = MyReader.GetString(3);

 str[4] = MyReader.GetString(4);

this.Invoke(new UpdateDelegate(UpdateLabel), new Object[] { str });

Also, all about 100 nodes :

cnt++;

if (cnt % 100 == 0)

{

  Thread.Sleep(0);                        

}

I know, I know, quick and dirty, but it helps to unfreeze the UI thread.

Then back in the main thread (UI = user interface), the delegate function:

private void UpdateLabel(string[] dataline)        

{

  Font boldFont = new Font  (treeGridView1.DefaultCellStyle.Font, FontStyle.Bold);

 AdvancedDataGridView.TreeGridNode node;

 node = treeGridView1.Nodes.Add  (null, "sometext", "tab", @"10/19/2005 1:02 AM");

node.ImageIndex = 0;

node.DefaultCellStyle.Font = boldFont;

node = node.Nodes.Add(null, "    " + dataline[0], dataline[1], dataline[2], dataline[3], dataline[4]);

for (uint h = 0; h < 5; h++)

   node = node.Parent.Nodes.Add(null, "    " + dataline[0], dataline[1], dataline[2], dataline[3], dataline[4]);

       }

I also have to say that my grid is usually loaded once, at the beginning, with normally no further large modifications (maybe some append for few nodes).

Regards,

Radu

# November 14, 2008 6:06 AM

Fooo said:

树形结构的DataGridView:CustomizingtheDataGridViewtosupportexpanding/collapsing(alaTreeGridView)

# November 26, 2008 12:59 AM

jerrydusing said:

I am using TreeGridView in my application but seems to have problem when a subnode is deleted - its sibling nodes will not be displayed corrctly when the parent node is collapsed and expanded. Can anyone suggest how to fix the problem.

Thanks

# November 28, 2008 8:24 AM

apan said:

Someone who has solved insert CheckBox control yeat?

# November 30, 2008 11:16 PM

Tim Gradwell said:

@jerrydusing

The TreeGridNode caches its index, but doesn't update the cached value when a node is removed.  My fix was to ALWAYS calculate the index instead of using the cached version

TreeGridNode:

public new int Index

{

  get

  {

     _index = this._owner.IndexOf(this);

     return _index;

  }

}

Hope that helps!

Tim

# December 10, 2008 6:39 AM

Angel said:

If you are interested, I've modified the TreeGridView in order to support DataSource with hierachical data in it (id, parent id).

This is the link:

http://www.advancedcomputing.ch/Blog/tabid/73/Default.aspx

Angel

# December 10, 2008 4:41 PM

jerrydusing said:

In my last post, I have highlighted problem with deleting nodes. I have found the bug. When a node is deleted, the sibling nodes after the deleted node must be reindexed. Because RowIndex is computed using the node index. To correct this bug, in TreeGridNode.cs you have to add the following method:

//JD's Note:

//  all child nodes have to be reindexed when

//  an intermediate node is removed, because

//  when this node is resited, its position

//  is computed based on its node index.

//        

internal protected void ReIndex(

  TreeGridNode node

)

{

  for (int i = this.Nodes.Count-1;

           i > node.Index ;

           i--

  )

  {

     this.Nodes[i].Index = i-1;

  }

}

The above method has to be called from the RemoveChildNode method. The edit method is as follows:

internal protected virtual bool RemoveChildNode(

  TreeGridNode node

)

{

  if ((this.IsRoot || this._isSited) &&

       this.IsExpanded

  )

  {

    //We only unsite out child node if we are sited

    //and expanded.

    this._grid.UnSiteNode(node);

   }

   node._grid = null;

   node._parent = null;

   node._level = -1;

   //JD's Note:

   // The node has to be reindexed so that it will

   // be sitedin the correct position within

   // the TreeGridView.

   this.ReIndex(node);

   return true;

}

I trust that help some of you who had a bit of problem with node deletion.

# December 12, 2008 2:49 AM

AngelOnLine said:

I've started to enhance the TreeGridView from Mark Rideout's blog

Now I've quite finished the work:

- Krypton layout and color schemes support (from Computerfactory.com)

- datasource support

- grouping by specific column

- true hierarchical display of data (using id and parentid column names, id = parentid for parent nodes)

- grouping level blocked on the first level (not for hierarchical)

- custom parent and childs images

- ...

check my site for code:

http://www.advancedcomputing.ch/

Regards /// Angel

# December 16, 2008 10:16 AM

Luis Aguilar said:

Hi Mark:

Just to mention a mistake that I have to use your control .. I'm using W2000 without VisualStyle ..

I come with an administrator account and there is no problem ... but if I enter as a normal user .. want to display the control I was a mistake.

I have concluded that the privileges of the account. Why? Thanks for your help and your valuable time

luisalberto_aguilar@hotmail.com

# December 17, 2008 7:47 PM

Boy2k said:

Hi Mark:

Just to mention a mistake that I have to use your control .. I'm using W2000 without VisualStyle ..

I come with an administrator account and there is no problem ... but if I enter as a normal user .. want to display the control I was a mistake.

I have concluded that the privileges of the account. Why? Thanks for your help and your valuable time

# December 17, 2008 7:52 PM

Prasad said:

Hi,

We have a checkbox column and I was trying to read all checked rows and it seems that I was not able to read collapsed rows data. any one has any workarounds for this.

ex: node["column1"].value says that column with name "Column1" can not be found

it works fine if I expand the nodes and tried to read it.

anythoughts over it???

# December 26, 2008 10:52 AM

Gerrard said:

Hi Mark

Excellent code. That's great

# January 6, 2009 3:10 PM

Alberto said:

Hi Mark,

First off, great job. This control has saved me a lot of time.

In our application we have some cases when a node is expanded to show around 350 child nodes, which is very slow. It takes around a minute to add them to the grid. I'm saying "add them" and not "show them" because in the first moment we only retrieve the parent nodes from the DB. Then if the user clicks on any plus sign the children are retrieved. I have checked that the method which gets the children takes only 1 second, so the problem occurs when adding them to the control.

Has anyone else come across this issue?

Thanks.

# January 9, 2009 4:39 AM

Sherene said:

Anyone have this control in VB.Net? Thanks.

# January 16, 2009 12:21 AM

Aster said:

For all those getting the error:

"Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'."

If you legitimately want to have a textbox column in front of the TreeGridColumn make the following change.

In TreeGridNode.cs at line 262 (Or find the following statement:

<---

if (cell.GetType().IsAssignableFrom(typeof(TreeGridCell)))

<---

Replace it with this if statement:

<---

if (cell.GetType().Equals(typeof(TreeGridCell)))

<---

The problem is the TreeGridColumn was inherited from the texBoxColumn so the original statement was giving a false positve.

Hope it helps.

# January 16, 2009 12:58 AM

prasad.k.s said:

Hi Mark,

   It is great component..I was hardly trying to build this kind of grid on my own. Im using in my current project to display parameters which were in some DDXML files.But there is one small requirement which i cant achive in this component is,During runtime,my applcn has to fetch the values from the device and will be displayed in new column..I want to update single column values during runtime..Is it achievable here? Plz help me.

# January 17, 2009 4:06 AM

Jiong said:

Prasad,

Every line belongs to a node. Every cell belongs to a line. So, reference the cell from the line in the node. Try node.Cells["columnname"].Value = newvalue.

# February 2, 2009 11:07 AM

Rob said:

Hi Mark,

  Its very pretty component..But i found some bug in tat..In child nodes,when i press escape key twice or tab key,entire application is crashing..It is crashing because of  Stack OVerflow exception..Is there any workaround for this issue..If so,plz help me fast..It is blocking my work..

          Tnx in advance.

# February 3, 2009 10:30 AM

Matthias Laabs said:

Dear Mark,

thanks for sharing this. As others pointed out already, expanding nodes becomes utterly slow even for just a few hundred nodes.

The problem lies in changing the CellStyle Padding in TreeGridCell.cs line 106.

Changing this seems to rebuild the geometry of the entire tree. But the Padding is not used in the base code but only in the overridden Paint method.

Thus an easy solution to speed up this widget is to introduce your own Padding field. This works fine as the vertical padding keeps constant and thus changes do not affect other cells.

Best Regards

Matthias

# February 17, 2009 11:40 AM

Hernan said:

Hi Mark:

Congratulations it's an excellent code , thank you so much

# February 17, 2009 5:42 PM

Madhan said:

Great contribution. Thank you very much.

# March 2, 2009 9:30 AM

Pierre said:

Hi Mark,

I have a problem with the selection of rows in the treegridview.

I have 2 classes, Parent and Child.

I fill the treegridview as you did in your sample:

node = treeGridView1.Nodes.Add for Parents objects and

node = node.Nodes.Add for Child objects.

I use node.Tag for saving both Parent and Child objects in the treeGridView because I don't have unique id to retrieve these objects.

I use treeGridView.SelectionChanged event to detect selection changes.

The proble is:

When I select a Parent row, the Tag object I got from treeGridView.SelectedRows[0] in the SelectionChanged event is a Child object !

There is no problem when there is no Child object, I got the Parent object in the Tag field !

What am I doing wrong ?

Please help me.

Thanks in advance.

# March 11, 2009 9:36 AM

Pierre said:

Hi Mark,

I have a problem with the selection of rows in the treegridview.

I have 2 classes, Parent and Child.

I fill the treegridview as you did in your sample:

node = treeGridView1.Nodes.Add for Parents objects and

node = node.Nodes.Add for Child objects.

I use node.Tag for saving both Parent and Child objects in the treeGridView because I don't have unique id to retrieve these objects.

I use treeGridView.SelectionChanged event to detect selection changes.

The proble is:

When I select a Parent row, the Tag object I got from treeGridView.SelectedRows[0] in the SelectionChanged event is a Child object !

There is no problem when there is no Child object, I got the Parent object in the Tag field !

What am I doing wrong ?

Please help me.

Thanks in advance.

# March 11, 2009 11:12 AM

Kiran said:

Hi Mark

Your work is beyond appriciation. Its really really good. I am a new developer. I am trying to bind data from two tables (Master and Detail) into your control. Here a parent can have more than one child and a chid can also belong to more than one parent. I am not getting exactly how to do. Your help in this matter will be highly appreciated. my email address is koiralakk@yahoo.com.

Thanks.

# March 27, 2009 10:08 AM

nejc said:

This control is exactly what I need. But I am kind of new with visual studio. Two questions:

First, can I use this control in a Visual Basic project? And if, how do I include the control and then attach it to a form? Would I be able to see it in the Toolbar and use it like other controls?

Secondly, can this control be used both in Visual Studio 2005 and Visual Studio 2008?

Thnx in advance.

# March 31, 2009 11:28 AM

nafisa said:

hello sir,

please help me in finding a solution to "redrawing of child nodes after deletion in Mark Rideout's TreeGridView". Whenever i try deleting a node,all the other nodes get displaced.This happens when there is only 1 child node to a parent.

if you could atleast provide me the link to the latest version of TreeGridView,it would be of great help and i would be grateful to you.

Thanks in advance.

regards,

Nafisa.

# April 9, 2009 3:46 AM

Amadej Bukorović said:

Hi Mark,

Thank you for this great control. As far as the slow performance caused by setting the Padding goes (thanks for identifing the problem Matthias!), one easy solution is to calculate the padding inside OnPaint().

This is what I did roughly:

TreeGridCell.cs in function OnPaint():

replaced

Rectangle glyphRect = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1);

with

_lastKnownGlyphRect = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1);

and moved the call just before base.OnPaint().

Added

cellStyle.Padding = new Padding(_lastKnownGlyphRect.Right+_imageWidth, 0, 0, 0);

just before calling base.OnPaint().

Naturally, I hashed out setting this.Style.Padding at the end of UpdateStyle(). And I had to change OnMouseDown() and replace

if (e.Location.X > this.InheritedStyle.Padding.Left)

with

if (e.Location.X > _lastKnownGlyphRect.Right || e.Location.X < _lastKnownGlyphRect.Left)

Works much faster with larger number of elements now. :) Just be careful when using my code, I haven't tested it thoroughly yet. :P

# April 24, 2009 4:16 AM

Kate said:

About inserting new rows.....

Try in TreeGridView.cs in

internal protected virtual void SiteNode(TreeGridNode node)

in

while (currentRow.Level >= node.Level)

{

......

}

take off "="

while (currentRow.Level >/*=*/ node.Level)

{

......

}

Hope this helps.

# May 11, 2009 8:13 AM

Fix978 said:

I have written the code for sorting subnode..

----------------------------------------

In TreeGridNode add Public variable:

.....

public int OrderValue = -1;

public String OrderString = "";

.....

-----------------------------------------

in TreeGridNodeCollection add new enum:

public enum SortingType

   {

       Integer = 0,

       String = 1,

       none = 2,

          }

-----------------------------------------------

in TreeGridNodeCollection add new public void:

  public void CompareSorting(ListSortDirection Order, int StartIndex, SortingType type)

       {

          this._owner._grid.SuspendLayout();

          bool hadChildren = this._owner.HasChildren;

          bool IsExpand = this._owner.IsExpanded;

          this._owner.Collapse();

           switch (type)

           {

               case SortingType.Integer:

                   this._list.Sort(StartIndex, (this._list.Count - StartIndex), new CompareItem(SortingType.Integer, Order));

                   break;

               case SortingType.String:

                   this._list.Sort(StartIndex, (this._list.Count - StartIndex), new CompareItem(SortingType.String, Order));

                   break;

           }

           foreach (TreeGridNode node in this._list)

           {

               node.Index = this._list.IndexOf(node);                          

           }

           if (IsExpand)

           {

               this._owner.Expand();

           }

           if (!hadChildren && this._owner.IsSited)

           {

               this._owner._grid.InvalidateRow(this._owner.RowIndex);

           }

          this._owner._grid.ResumeLayout();

          }

---------------------------------------------------

in TreeGridNodeCollection add new Class Comparer:

  private class CompareItem : IComparer<TreeGridNode>

       {

           internal ListSortDirection _direct;

           private CompareInfo _compareInfo;

           SortingType sortType;

           public CompareItem(SortingType xsortType, ListSortDirection xdirect)

           {

               _compareInfo = CultureInfo.CurrentCulture.CompareInfo;

               sortType = xsortType;

               _direct = xdirect;

           }

           public int Compares(TreeGridNode item1, TreeGridNode item2)

           {

               if (item1 == null || item2 == null || sortType == SortingType.none)

                   return 0;

               switch (sortType)

               {

                   case SortingType.Integer:

                       {

                           if (_direct == ListSortDirection.Ascending)

                           {

                               return item1.OrderValue.CompareTo(item2.OrderValue);

                           }

                           else

                           {

                               return item2.OrderValue.CompareTo(item1.OrderValue);

                           }

                       }

                   case SortingType.String:

                       if (_direct == ListSortDirection.Ascending)

                       {

                           return _compareInfo.Compare(item1.OrderString, item2.OrderString, CompareOptions.None);

                       }

                       else

                       {

                           return _compareInfo.Compare(item2.OrderString, item1.OrderString, CompareOptions.None);

                       }

                   default: return 0;

               }

           }

           public int Compare(TreeGridNode item1, TreeGridNode item2)

           {

               return Compares(item1 as TreeGridNode, item2 as TreeGridNode);

           }

       }

-------------------------------------------------

Use this code with:

NODE.Nodes.CompareSorting(order, index, type)

Regards,

Fix978

# May 22, 2009 10:23 AM

tnguyen said:

Hello,

I have problem with Insert a node in TreeGridView. The new node is always added in the last of list. Do you have any sample code for insert node with index? If you have please give me.

Thanks,

Thang

# June 15, 2009 5:30 AM

Adarsh said:

Hi Mark,

Thanks for writing such a usefull component. In my case I'm using your control to display live data from Bloomberg. This data refreshes very frequently say every 5 to 10 sec. The challenge that m facing is m not able to fully expand the tree as by the time I expand a node the grid refreshes itself and shifts back to its initial position. So I would like to know how to display the tree inside gridview in the fully expanded manner. Would really appreciate if you can provide a code snippet for the same. I'm using .net 2.0, C#.

# June 25, 2009 12:31 AM

Spingkoy said:

Hi Mark,

Very nice control. But i have some problem doing this one: This is just a sample scenario, a user selects a country under that, there are places he/she selects by checking the Visit column w/c is a DataGridViewCheckBoxColumn. What happen on this is that all rows have checkbox like this :

(TreeGridColumn) (DataGridViewCheckBoxColumn)

CountryColumn         Visit  

- United States        []

   Atlanta            []

   New York           []

   Chicago            []

- Philippines          []

   Manila             []

   Cebu               []

what i really wanted is the parent node will not have checkbox so it will appear like this :

(TreeGridColumn) (DataGridViewCheckBoxColumn)

CountryColumn         Visit  

- United States      

   Atlanta            []

   New York           []

   Chicago            []

- Philippines    

   Manila             []

   Cebu               []  

How will i hide checkbox of specifi cell?

Thanks a lot.

# July 3, 2009 5:30 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker