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. Some people have been able to modify the code to run without Visual Styles. See this post for details.

Original Code:

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:


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!


Comments (239)

  1. Paul says:

    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.

  2. amitchat says:

    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?


  3. Kevin Dente says:

    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.

  4. ZAW says:

    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?



  5. Joo Lee says:

    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!

  6. Ankur Gurha says:

    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.



  7. zmt says:

    i got errors

  8. Jim Peterson says:

    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!

  9. ale says:

    Very nice and usefull!

  10. Martin says:

    Great works, thanks for sharing!

  11. Jithesh says:

    DID this Support DRAG & DROP

  12. Fil says:

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

  13. Logan says:

    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:

  14. Shobh99 says:

    Thanks a lot for the code.

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

    It was very useful for me.

  15. SR says:

    Looks wery good, but can I set focus to a special row? The "SelectedRows"is ReadOnly…

  16. Mike says:

    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.

  17. Srini says:

    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.

  18. romz says:

    how to bind using dataset?

  19. harlequin says:

    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

  20. Henry Vu says:

    Your treegridview have bug if VisualStyle is not enabled on your windows.

    Can you fix it? I really need your code. Thanks your code

  21. Dwight Kulkarni says:

    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.

  22. azuro (at) gawab (dot) com says:

    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:


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

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


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


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


                           //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));




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





  23. _JERKER_ says:

    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…?


  24. JerryNixon says:

    Beautiful. Move it to SourceForge (or somewhere)!

  25. jk says:

    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

  26. Tim Cartwright says:

    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 :



    ——–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.

  27. staceyw says:

    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.

  28. John Bollwerk says:


    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?



  29. Jason Ellenbogen says:

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


  30. Chad says:

    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

  31. Patrick says:

    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?


  32. vishala says:

    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.

  33. erol says:

    this is really cool.but adding databinding property would be perfect.if anybody had made this, please show the code:) i really need it.

  34. eltonic40 says:

    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?

  35. Zoki Manas says:

    it is a great code… there any way to put check boxes instead of text boxes….I need something like : check Parent node…check all child nodes….

  36. Yuval Ararat says:

    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…

  37. Zoki Manas says:

    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?

  38. rape stories says:

    Your article is prety nice. It’s a pity that i didn’t see it more later.

  39. Kris Wragg says:

    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…

  40. I need databinding, may be i make this.

    Vary thanks for the this control !

    Best regards to autor !

  41. JorginhoPC says:

    The tree is expanded.

    how do I get the current node?

    I need to get the values on the click or double click…

  42. webcliff says:


    How can I toggle the highlighting on a row with every mouse click?

    I tried to override SetSelectedRowCore with no luck.

  43. Miselly says:

    thanks for code.

    but,i hope VB source

  44. Pradeep says:

    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

  45. Julia says:

    Good work!

    Can I have it in  2003 version?


  46. amk says:

    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

  47. nrasinec says:


    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.


    Rasinec Ninoslav

  48. Sima says:

    Very nice. What about databinding, did anybody made it?

  49. Eli says:

    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?


  50. Lex says:


    Who solved the error :

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

    Thank you

  51. Natarajan says:


    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.



  52. Baskar C.G says:

    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"

  53. ramazan says:

    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?

  54. Jason says:

    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.

  55. Justified says:

    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


  56. Tzippy says:

    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:

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


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




                       node._grid.rClosed = graphics;

                       node._grid.rClosed.DrawImage(, 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.

  57. Vikaash says:

    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 ?

  58. BillB says:

    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


    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.



  59. Ray says:

    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)

  60. Juan Azabache says:

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

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

  61. Brian Madsen says:

    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!!

  62. Chintan says:

    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.



  63. Mark Rideout says:

    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,


  64. Focus to Next Cell says:

    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 :

  65. ... says:

    Great site! Good luck to it’s owner!

  66. Isha says:

    Really a wonderful job.

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

  67. Agus Sanjaya says:

    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?

  68. david says:

    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.

  69. MDT says:

    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.


  70. bob says:

    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

  71. Shashank says:

    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.



  72. CH says:

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



  73. Faisal says:

    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

  74. Khaleed says:


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


  75. Mostafa Iqbal says:

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

  76. Hamid says:

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

  77. Karthik says:

    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.


  78. Inserting new rows says:

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

  79. Ehab Hosny says:

    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

  80. dgcl says:

    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!

  81. Aarthi says:

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

  82. kriz says:


    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?

  83. Ehab Hosny says:

    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?

  84. Realite says:

    Woowww… It’s a good and useful component. Thank’s a lot…

  85. tsueng chen says:


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

  86. Poonam says:


    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?


  87. Karl says:

    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 !!

  88. Brad says:

    How do I get the currently selected Node?

  89. jasonlaw says:

    How can I set focus to a special row?

    Please help…..

  90. Jay R. Wren says:

    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?


  91. Bill Davis says:

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

  92. Alex Efimov says:

    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.  😉

  93. Jay R. Wren says:

    "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.

  94. Yogesh says:


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


  95. Yogesh Nayak says:


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


  96. Marlou says:

    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.

  97. Nal.S says:

    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…



  98. civa_i_shone says:

    awesome dude very impressed with this stuff

    helped us so much


  99. Josh Hunt says:

    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.

  100. rama charan says:

    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.

  101. Anton says:

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

  102. yannick says:


    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

  103. Spoook says:


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

    But it has some bad sides.

    one is this;


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


               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");


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

               node = new AdvancedDataGridView.TreeGridNode();                        

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


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

               node = new AdvancedDataGridView.TreeGridNode();            


               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

  104. Billy W. says:

    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….

  105. Functional Illiterate says:

    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.


  106. Kornel says:

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

    am i too late?

  107. Juliette says:

    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.

  108. mscirri says:

    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.

  109. Matt Hanson says:

    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.


  110. ManiX says:

    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,


    mail2manix [at] gmail [dot] com

  111. Murad says:


    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#RiskReportTreeGridViewTreeGridView.cs:line 42′




    With what it can be connected?

  112. commenter says:

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

  113. imran says:

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

    imran saeed


  114. Yagnesh says:

    Hi Mark,

    This is very useful.

    How do we do for DataTable/DataView as DataSource?

    Something like :


       ItemNumber            ItemQty


       ItemNumber            ItemQty

  115. waspy59 says:


    it’s a very nice code. do you have it for C# is unknow for me….


  116. Guilherme Melo says:

    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




           return ds;




           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 🙂

  117. Vidya K.A says:

    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..

  118. 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

  119. Greg Shebert says:

    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?



  120. Marc G. says:

    Brilliant control! Thank you Mark!

  121. Rupinder says:


    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.

  122. One more says:

    Sort columns:

    private void treeGridView1_CellClick(object sender, DataGridViewCellEventArgs e)


               if (e.RowIndex < 0)


                   foreach(TreeGridNode node in this.treeGridView1 .Nodes)




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



  123. Martin says:

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

  124. Marco Aurélio Gerônimo says:

    Hi Mister….

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



  125. d4dennis says:

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

  126. JM says:

    Hello, nice control.



  127. Peter says:

    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.



  128. 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)





    private void expandNode(TreeGridNode node)


               if (node.Nodes.Count > 0)



                   foreach (TreeGridNode subNode in node.Nodes)






    [Description("Collapse all nodes")]

    public void CollapseAll()


               foreach (TreeGridNode node in this.Nodes)





           private void collapseNode(TreeGridNode node)


               if (node.Nodes.Count > 0)


                   foreach (TreeGridNode subNode in node.Nodes)








    recursion rocks

  129. Marcelo Fabiano says:

    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

  130. Gary says:

    Plz someone convert it to vb version please….

  131. Andrej Vilinski says:

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


    /// <summary>

    /// Expands all nodes.

    /// </summary>

    [Description("Expands all nodes")]

    public void ExpandAll()


    foreach (TreeGridNode node in Nodes)



    /// <summary>

    /// Collapses all nodes.

    /// </summary>

    [Description("Collapses all nodes")]

    public void CollapseAll()


    foreach (TreeGridNode node in Nodes)



    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)





    /// <summary>

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

    /// </summary>

    public void ExpandAll()


    if (Nodes.Count > 0)



    foreach (TreeGridNode subNode in Nodes)




  132. Jiong says:


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

  133. Jiong says:


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

  134. Bch says:

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

  135. nerix says:


    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.


  136. Jiong says:

    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.

  137. Radu says:


    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:


    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.


    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;


    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 :


    if (cnt % 100 == 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).



  138. Fooo says:


  139. jerrydusing says:

    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.


  140. apan says:

    Someone who has solved insert CheckBox control yeat?

  141. Tim Gradwell says:


    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


    public new int Index




         _index = this._owner.IndexOf(this);

         return _index;



    Hope that helps!


  142. Angel says:

    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:


  143. jerrydusing says:

    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 ;




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




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

        //and expanded.



       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.


       return true;


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

  144. AngelOnLine says:

    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

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

    Regards /// Angel

  145. Luis Aguilar says:

    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

  146. Boy2k says:

    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

  147. Prasad says:


    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???

  148. Gerrard says:

    Hi Mark

    Excellent code. That’s great

  149. Alberto says:

    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?


  150. Sherene says:

    Anyone have this control in VB.Net? Thanks.

  151. Aster says:

    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.

  152. prasad.k.s says:

    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.

  153. Jiong says:


    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.

  154. Rob says:

    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.

  155. Matthias Laabs says:

    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


  156. Hernan says:

    Hi Mark:

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

  157. Madhan says:

    Great contribution. Thank you very much.

  158. Pierre says:

    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.

  159. Pierre says:

    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.

  160. Kiran says:

    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


  161. nejc says:

    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.

  162. nafisa says:

    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.



  163. Amadej Bukorović says:

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


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


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

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


    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)


    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. 😛

  164. Kate says:

    About inserting new rows…..

    Try in TreeGridView.cs in

    internal protected virtual void SiteNode(TreeGridNode node)


    while (currentRow.Level >= node.Level)




    take off "="

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




    Hope this helps.

  165. Fix978 says:

    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)



              bool hadChildren = this._owner.HasChildren;

              bool IsExpand = this._owner.IsExpanded;


               switch (type)


                   case SortingType.Integer:

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


                   case SortingType.String:

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



               foreach (TreeGridNode node in this._list)


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


               if (IsExpand)




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







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




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



                       case SortingType.String:

                           if (_direct == ListSortDirection.Ascending)


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




                               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)



  166. tnguyen says:


    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.



  167. Adarsh says:

    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#.

  168. Spingkoy says:

    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.

  169. James D says:

    Thank you Mark for such a great control. You have saved me many hours of hair pulling gui work. :~)

    As for Spingkoy’s  question stated above. You can just change the cell which you want the check box removed from to a DataGridViewTextBoxCell

    // Add a new node to your tree grid view.

    TreeNode node = treeGridView1.Nodes.Add("", "");    

    // remove the cell with the check box.


    //Add a DataGridViewTextBoxCell

    node.Cells.Add(new DataGridViewTextBoxCell());

  170. Vivek Varma says:

    for following xml

    <Root><Row col1="1" col2 ="2" col3 ="3">

    <Row col1="11" col2 ="12" col3 ="13">

    <Row col1="111" col2 ="112" col3 ="113">

    <Row col1="1111" col2 ="1112" col3 ="1113">

    <Row col1="11111" col2 ="11112" col3 ="11113">

    <Row col1="111111" col2 ="111112" col3 ="111113" /></Row></Row></Row></Row></Row>

    <Row col1="4" col2 ="5" col3 ="6" >

    <Row col1="41" col2 ="51" col3 ="61" /></Row></Root>

    Use this code for recursive call

    private void Form1_Load(object sender, System.EventArgs e)


    attachmentColumn.DefaultCellStyle.NullValue = null;

    // load image strip

    this.imageStrip.ImageSize = new System.Drawing.Size(16, 16);

    this.imageStrip.TransparentColor = System.Drawing.Color.Magenta;

    this.imageStrip.ImageSize = new Size(16, 16);


    treeGridView1.ImageList = imageStrip;

    // attachment header cell

    this.attachmentColumn.HeaderCell = new AttachmentColumnHeader(imageStrip.Images[2]);

    XmlDataDocument x = new XmlDataDocument();

    x.Load(@"New Text Document2.xml");

    TreeGridNode node;

    foreach (XmlNode x1 in x.FirstChild.ChildNodes)


    node = treeGridView1.Nodes.Add(null, x1.Attributes[0].Value, x1.Attributes[1].Value, x1.Attributes[2].Value);

    node.ImageIndex = 1;

    LoadXMLNodes(x1, treeGridView1.Nodes, node);


    public void LoadXMLNodes(XmlNode xmlnode, TreeGridNodeCollection nodes, TreeGridNode node)

    {TreeGridNode tvNode = new TreeGridNode();

    foreach (XmlNode x1 in xmlnode.ChildNodes)

    {tvNode = node.Nodes.Add(null, x1.Attributes[0].Value, x1.Attributes[1].Value, x1.Attributes[2].Value);

    LoadXMLNodes(x1, nodes, tvNode);}}

  171. Muammar says:

    Hello everyone,

    How would you add a treeNode to the control?? Any smart way to maybe convert/rebuild it to a treeGridNode??

    <b><font color=#00aa00>

     TreeNode tn = new TreeNode();





     treeGridView1.Nodes.Add(tn); //Will only add the first node


  172. Shawn says:

    I was wondering if anyone has written code to stop double clicks from occuring when clicking on the +/- tree node portion.  I’d prefer to disable that if possible.  Thanks!

  173. R Singh says:

    Hi Mark,

    This is a real nice code. Do you have anything like this for asp .net web applications. I have a requirement to create a activity schedule tree grid in .net web application. Please post something if you have any idea or code realted to this.


    R Singh

  174. Marcelo. says:

    First of all, congratulations this component is very useful.

    Has someone got DefaultCellStyle.Format working?


                                          DataGrid.Columns[I].DefaultCellStyle.Format = "N2";

    It is not formating cell to numeric. Am I missing sth?

    thanks a lot.

  175. Mike says:

    Hi any one was able to add a checkbox and select the parent checkbox as well all the child’s?

    (Example click on parent checkbox auto check child’s checkbox:)

    [Col01]     [Col02]

    Item01       [x]

    subitem01   [x]

    subitem02   [X]

    subitem03   [x]

    Item02       [ ]

    subitem01   [ ]

    subitem02   [ ]

    subitem03   [ ]

    Item03       [x]

    subitem01   [x]

    subitem02   [X]

    subitem03   [x]

    Item04       [ ]

    subitem01   [ ]

    subitem02   [ ]

    subitem03   [ ]


  176. SAGA says:

    Hey Markie boy thanks for the very useful control. really appreciate it!

    thanks also to:

    azuro (at) gawab (dot) com

    for fixing the issue (not workin’ w/o VisualStyles)


    for giving advice on how to use the control on

    Damn Markie boy, can i be your apprentice? 🙂

  177. Bart says:

    Hi there, someone 3 years ago asked why this control becomes unusable with big amount of rows :). I found this problem now… It’s old bug in styles of DataGridView that causes one thing… first row is added in 3 miliseconds and 50th row is added in 30 miliseconds and 100th in 80 miliseconds and so on ;).

    Let’s get to the point… Code should look like this:

    if (preferredSize.Height < _imageHeight)


           Style oStyle = this.Style.Clone();

           oStyle.Padding = new Padding(p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN,

                            p.Top + (_imageHeight / 2), p.Right, p.Bottom + (_imageHeight / 2));

           _imageHeightOffset = 2;// (_imageHeight – preferredSize.Height) / 2;

    this.Style = oStyle;




    Style oStyle = this.Style.Clone();

           oStyle.Padding = new Padding(p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN,

                            p.Top, p.Right, p.Bottom);

    this.Style = oStyle;


    instead of

    if (preferredSize.Height < _imageHeight)


           this.Style.Padding = new Padding(p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN,

                            p.Top + (_imageHeight / 2), p.Right, p.Bottom + (_imageHeight / 2));

           _imageHeightOffset = 2;// (_imageHeight – preferredSize.Height) / 2;




           this.Style.Padding = new Padding(p.Left + (level * INDENT_WIDTH) + _imageWidth + INDENT_MARGIN,

                            p.Top, p.Right, p.Bottom);


    If you step in Microsoft’s code in VS you can see that if you set Padding of existing cell’s style OnPropertyChanged event is raised. I didn’t check further but there are plenty of things inside which are not working well and cause huuuuge overhead. Therefore remember to ALWAYS clone styles of datagridview when you work with it :).

  178. bsk says:

    The the following to methods to the TreeGridNode class. Call them from within your program as in "_node.MoveUp()" or "_node.MoveDown()".

           public void MoveUp()


               int iIndex = RowIndex;

               TreeGridNode _oldParent = this.Parent;


               _oldParent.Nodes.Insert(–iIndex, this);

               _grid.CurrentCell = Cells[0];


           public void MoveDown()


               int iIndex = RowIndex;

               TreeGridNode _oldParent = this.Parent;


               _oldParent.Nodes.Insert(++iIndex, this);

               _grid.CurrentCell = this.Cells[0];


    These will move the entire selected node (and it’s children) up or down one row.

  179. John Sewell says:

    Very nice control, but I just spent a while chasing down an issue when using it on a certain users box, that I thought I’d share.

    If the user has their theme set to Windows Classic the control will fail as it makes use of the visual styles without checking if they are available.  This is the offending line:

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

    I did have some luck, changing this to just define the variable without initialisation, then on the constructor actually set it up if Application.RenderWithVisualStyles was true.

    I got other errors down the line after that, but have not had a chance to debug them out, this was a small personal tool so for the moment I’m just reworking the UI to not use this for the moment.

    Much as it’s not quite working for me, many thanks for making this available, on the machines it does work on it’s brilliant.

  180. Jim LaVine says:

    Thanks Mark for the good work.  Can you explain how to support allowing the user to add and delete rows?

  181. Deepak says:

    Getting Error while running on Win 2003

    Error Msg:

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

    Can you help me out in resolving this.

  182. this is a very good article which binds datagridview just alike treeview, i like to use this feature in my site.

  183. Cleo says:

    Great contribution. Thank you very much.

    Anyone have this control in VB.Net?


  184. TX says:

    You are genious!

    Thanks for your sharing.

  185. Bryan Thueson says:

    Hello Mark,

    We like this grid but are having a problem when the user trys to use it when his XP system is set to "XP Classic" mode.  Have you had or anyone else had any experience with that previously?

  186. jranlin says:

    I just want to know how to insert node.


  187. Eg Gigo says:

    treegridview make ensurevisible and find node?

  188. sayed says:

    Hi Mark,

    I’m using VS2008.I want to use this sample in my project with checkboxes inside datagridview.When I d/w ur sample and run in VS2008 its showing error.Kindly let me know As early as possible how to work with this control in VS2008 is really helpful for me.

  189. sayed says:

    Hi Mark,

    I want one sample application in which u have implemented this one.Please try to send to As its really helpful for me.Waiting for your mail Mark.

    Thanking U

    Sayed Ali

  190. Daniele says:


    I’m trying to use it in 2008. The language is Visual basic, but I can’t see the component after the add reference..

    Can you explain me how to insert it as component?

    I also tried to create the grid from code with

    "Dim grd_tree As AdvancedDataGridView.TreeGridView

    grd_tree = New AdvancedDataGridView.TreeGridView

    grd_tree.Top = PictureBox3.Height

    grd_tree.Left = 0

    grd_tree.Width = Me.ClientRectangle.Width

    grd_tree.Height = Me.ClientRectangle.Height

    grd_tree.Visible = True"

    But I can’t see it.

    Thanks! See you soon

  191. Nivedita.D says:

    We have used this control in our C# project and I require to resize the columns programmatically.

    In the grid, first column is a TreeGridImageColumn, Second is TreeGridColumn and Third is DataGridViewTextBoxColumn. How should I loop through the  columns so that I can resize each column.

    Foreach (TreeGridColumn ) – does not work


    For (Int32 iCol;iCol <= TreegridView.ColumnCount -1;iCol++)


    TreeGridView.Columns(iCol).Width //Does not Work


    Please somebody help me on this. It is Urgent!


  192. Rodrigo says:

    Hi everyone!

    i want to ask if i can get editable cells with this control?

    Could someone convert this code to


  193. Marlon says:

    Very nice piece of work! These are the type of projects that are worth paying for!

    Kudos to the author!

  194. First off – wanted to say I love this control and am using it in quite a few places.  Very well done!

    I am having a bit of an issue, however.  It seems the SelectionChange event is firing for every node that is added to the TreeGridView, and also fires when you do TreeGridView.Nodes.Clear().  Is there any way to stop this from firing in these types of situations?  It ends up really lagging out the display.  When I do .Rows.Clear() they instantly disappear but that doesn't work for the TreeGridView as it throws up errors.  Thanks.

  195. Nuit says:

    There are a lot of posts about problem of inserting nodes. It seems that I have found the decision.

    Firstly, do as Kate wrote, i.e. in TreeGridView.cs in

    internal protected virtual void SiteNode(TreeGridNode node)


    while (currentRow.Level >= node.Level)


    take off "="

    i.e. must be so:

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


    Secondly, in TreeGridView.cs in

    internal protected virtual bool InsertChildNode(int index, TreeGridNode node)


    //TODO: do we need to use index parameter?

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


    write this code


    for (int i = index; i < this.Nodes.Count; i++)

      this.Nodes[i].Index = i;


    In my project it works.

  196. Woody says:

    Realy nice work man! Tnx a lot!

  197. Ramesh Naidu says:

    Thank you very much for your code……

    It is very helpful…

    I have some problem with reading the node values in tree grid view.

    I appended data to tree grid view, from database.

    Now my requirement is to read the selected value in tree grid view.

    Is it possible?

    if, yes, then please share with me..

    Thanks in Advance

    Ramesh Naidu

  198. Tamour says:

    Only two words.



  199. ABC says:

    The tree is expanded.

    how do I get the current node?

    I need to get the values on the click or double clic

  200. ABC says:

    I need to get the values on the click or double click…

    HasChildren…IsParent doesnt work…

    Please help

  201. Nivedita says:

    Can i get the selected node in the selected row.

    Need to add code to display context menu…Please help…


  202. Luis Roa says:

    How to select a TreeNode using Rows.Index?

  203. Luis Roa says:

    Hi Mark

    Felicidades!!! 😉

    how can I get the node of a row from the RowIndex property?

  204. Soumen Roy says:

    Please tell me anyone if it will work on WinDows Server 2003 / 2008. My exe runs on XP SP3 nicely but throws no error in Windows Server, though no dialog box is opening. I cant understand whether the problem is in my code or the control is not compatible with WinDows Server 2003 / 2008. Framework 3.5 is installed in the Server

  205. Chris says:

    Hey I found your control and its just what I was looking for!   I'm having trouble adding nested nodes in the control.  I'll explain my situation:

    I have a list of objects that have name and date attributes.  I would like to iterate the list and get the date of each and add the name as a child node.  I basically want the control to behave like the main form region in Outlook would where you have the date as a collapsible node and mail items as child nodes.  For some reason when I add the nodes it does not add them correctly.  Here is my code:

    private void loadTGV(List<DFEvent> tmp)


               // remove all nodes


               // clear all data



               AdvancedDataGridView.TreeGridNode node = null;


                    * Today (dd-MMM-yyyy)

                    *      Event Name

                    * Last Week

                    *      dd-MMM-yyyy

                    *          Event Name


               // loop all events

               foreach (DFEvent df in tmp)


                   // if top level label not in list, add it.                

                   if (!(this.checkLabel(this.getDateRange(this.getDateDifference(df.DtOccured)))))


                       node = this.eventsTGV.Nodes.Add(this.getDateRange(this.getDateDifference(df.DtOccured)));

                       // do not add date level label for "today" or "2 Days Ago.."

                       if (this.getDateDifference(df.DtOccured) <= 6) continue;

                       node = this.getNode(this.getDateRange(this.getDateDifference(df.DtOccured)));

                       node = node.Nodes.Add(string.Format("{0:dd-MMM-yyyy}", df.DtOccured));


                   // if top level in list, check if event date not in list, add it

                   else if (!(this.checkDate(df.DtOccured)))


                       // do not add date level label for "today"

                       if (this.getDateDifference(df.DtOccured) <= 6) continue;

                       node = this.getNode(this.getDateRange(this.getDateDifference(df.DtOccured)));

                       node = node.Nodes.Add(string.Format("{0:dd-MMM-yyyy}", df.DtOccured));


                   // add event name

                   node = this.getNode(string.Format("{0:dd-MMM-yyyy}", df.DtOccured));

                   node = node.Nodes.Add(df.Type.ToString());



    I'm sorry if this is not a great place to post this question = S

    Any guidance you can provide will be greatly appreciated.


  206. niclas says:

    Hi Mark,

    I believe your component is a pretty good component and quite usefull. I'm using your treegridview for my project, but I got a problem now. When I'm refreshing the data in the grid, looks like the state is not being saved. So, if I expand one of it's row, when my thread refresh the grid, the rows become collapsed and back to the first time before I 'touch' the grid. Is there any way to keep the session of this grid, so even I refresh the data in the grid, the row(s) still expanded? Please help to reply to my email Thanks before.

  207. Ramiclin says:

    Any idea how can I use this control without Visual Styles enabled?

  208. ? says:

    This control looks very promising. My compliments on an excellent job.

  209. weitzhandler says:

    I am looking for an implementation of a DataGrid-TreeView hybrid. actually same idea like above but should be a DataGrid.

  210. keyskid says:

    Thanks for the TreeGridView, it's what i'm looking for. But i face some abnormal behavior for this control.

    I have populated TreeGridView with 2 levels of nodes, (i.e. level 1 refers to parent node, level 2 refers to child node).

    While i'm trying to dynamically remove the last child node from the current parent and add it to another parent, the TreeGridView show the child node as the first row while its parent as the last row. May I know why? How to rectify it?

    However, I know the hierarchy is correct because when I double click the new parent node at the last row, it'll collapse the childnode even though it's at first row. But why the child is not displayed as the next row under the parent?

    Really appreciate if anyone can help. thanks a lot.

  211. keyskid says:

    Thanks for the TreeGridView, it's what i'm looking for. But i face some abnormal behavior for this control.

    I have populated TreeGridView with 2 levels of nodes, (i.e. level 1 refers to parent node, level 2 refers to child node).

    While i'm trying to dynamically remove the last child node from the current parent and add it to another parent, the TreeGridView show the child node as the first row while its parent as the last row. May I know why? How to rectify it?

    However, I know the hierarchy is correct because when I double click the new parent node at the last row, it'll collapse the childnode even though it's at first row. But why the child is not displayed as the next row under the parent?

    Really appreciate if anyone can help. thanks a lot.

  212. keyskid says:

    Found the solution for problem of displaying child node at first row by putting an extra line in TreeGridNode.cs

    Within the method of :    internal protected virtual bool AddChildNode(TreeGridNode node)

    after line of :     node._grid = this._grid;

    add a line of:    node._index = this.childrenNodes.Count – 1;


    internal protected virtual bool AddChildNode(TreeGridNode node)


    node._parent = this;

    node._grid = this._grid;

           node._index = this.childrenNodes.Count – 1;

    // ensure that all children of this node has their grid set

    if (this._grid != null)


    if ((this._isSited || this.IsRoot) && this.IsExpanded && !node._isSited)


    return true;


  213. zavcorp says:

    hello i really thank you for this example!!!

    very good

    im sorry but i have a one question:

    ¿this example have design in web application using

    i need design this example but in web application

    i really need help for this!!!

  214. Christopher King says:

    This is a very useful component; thanks very much for creating it and to everybody else for contributing to it's evolution.  One thing though; is there are reason for the UnSiteAll() call that is being made in the Dispose() implementation of the TreeGridView class?  This ends up taking a fair bit of time when there are alot of items and I can't see that there is anything that it needs to be doing (wrt un-managed resources etc.).

  215. Pedros says:

    Hi, thanks for your code. That's what I really need now. It's awesome. 🙂

  216. NaynaK says:

    Hi Mark,

    Thanks for sharing this tree grid view.

    In the note, you have mentioned that code change has to be made if visual styles are not used.

    Can u help me with the necessary code change i need to make as i don't want to use any visual styles.

    If change my systems Visual Effects, i get a problem using the tree grid view.

    Can u please let me know the changes i have to make in the code?

    Waiting for your reply.



  217. Frontier says:

    With regard to Visual Effects, check out the solution at:…/b1167539-1f93-4d30-87cd-04f25626e78d

  218. mafc says:

    How i can know what item is selected in the treeview column?


  219. swfehr says:

    I too ran into the problem described by Aster on 16 Jan 2009 12:58 AM (page 11 of these comments).

    When the first column is a DataGridViewTextBoxColumn (or anything not assignable to a TreeGridColumn), the following exception is raised:

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

    While Aster's solution will work, my solution would instead be:

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


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


    Replace it with this if statement:


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


    The problem is the TreeGridCell object is being assigned *from* the cell, not the other way around.  I believe this was the original intent of the coder.

    P.S. Mark, thanks for sharing this customized control!

  220. Geoff says:


    Does someone solves the problem of selection when the control is instanciate.

    The SelectionChanged event is well fired but the TreeGridNode that fired the event is "inexistant".

    After, I have change the selection and re-select the first row (manually by clicking with the mouse), all works correctly.

    Thanks for answers


  221. Shruthi says:

    Hi.. Am doing Windows application..In datagridview i have 4 columns. Student Name as Column1, present as checkbox,Absent as checkbox,leave as chechbox.. I have to click present or absent or leave for respective student name, Here i have to bind student name from backend, Am not getting how to bind data of one column from backend to one column of datagridview.. please help me.. if possible please mail me.. Thanks in advance

  222. Adam says:

    Thanks a lot for this control – we're using it to display a list of aggregated search results (total, average time, max time, etc.), where each result contains a bunch of versions, that when expanded display the same information for just that version. This is exactly the sort of display we needed.

    Of course, I needed to get sorting working first, and I fiddled around a bit getting the keyboard to respond more expectedly, but this definitely saved me a load of time compared to having to implement a control like this from scratch. Thanks for making it available!

    (It does strike me as vaguely silly that it requires non-classic visual style to run properly out of the box, when it was so trivial to fix, but whatever. It was also trivial to fix.)

  223. Ralph Eggelsberger says:

    GREAT work!

    I've found another small problem. When Removing child nodes, there has to be a reindexing too. So the routine should look like (TreeGridNode.cs):

    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.




        for (int i = node.Index; i < node.Parent.Nodes.Count; i++)

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

        node._grid = null;

        node._parent = null;

        return true;


  224. breeze says:

    is it possible to set true righttoleftlayout property of this component?

  225. Farha :) says:

    Thanks!!Now I have make my own gridview similar to you and its working!!!Nice Work!

  226. Marco F says:

    Incredible work!!! congrats… now is it possible to add checkmarks to the tree? That would make this control a killing one!

  227. Umar says:

    Hi, Thanks for such a nice customize control. I used your control and its very help ful. Now what i want to add a data grid view as a child node in a current data grid veiw. Can you help me for that ? I'm very thankful to you

  228. Added VisibleGridCell : DataGridViewButtonCell overloaded Paint to INVISIBLE the cell.Visible = false;

    namespace AdvancedDataGridView


       public class VisibleGridCell : DataGridViewButtonCell


           private bool m_IsVisible;

           public VisibleGridCell()


               this.m_IsVisible = true;


           public bool Visible


               get { return m_IsVisible; }

               set { m_IsVisible = value; }


           public override object Clone()


               VisibleGridCell c = (VisibleGridCell)base.Clone();

               c.m_IsVisible = this.m_IsVisible;

               return c;


           protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds,

               int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue,

               string errorText, DataGridViewCellStyle cellStyle,

               DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)


               if (!m_IsVisible) return;

               base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue,

                   errorText, cellStyle, advancedBorderStyle, paintParts);


           public TreeGridNode OwningNode


               get { return base.OwningRow as TreeGridNode; }



       public class VisibleGridColumn : DataGridViewButtonColumn


           public VisibleGridColumn()


               this.CellTemplate = new VisibleGridCell();


           public override object Clone()


               VisibleGridColumn c = (VisibleGridColumn)base.Clone();

               return c;




  229. Tomas Rodriguez says:

    This is a great contribution. Thank you. I have your component running seamlessly in a rather complex application. However, I have a problema whe I add a second treegridview inside a the same tab control but in different tabs i get an error. Is there any limitation in the number of treegridview controls you can use?

    Thank you.

  230. Mark Rideout says:

    There isn't any limitation though what might be occurring is that the TreeGridView in the second tab is not being created visually yet or data hasn't been associated yet. Any initialization code where you are adding content to the TreeGridView on the invisible tab might error out.

  231. Tomas Rodriguez says:

    Hi Mark,

    How can I check if a node is expended? Is there a IsExpanded property available?


  232. Tomas rodriguez says:

    Hi Mark,

    Everything is working now. I have a question:

    is there a "expanded" property in your control? I would like to know if a node is expanded at run time.

    Thanks a lot.

  233. Mark Rideout says:

    There isn't a public IsExpanded property on TreeGridNode but it is easy to do since there is an internal IsExpanded bool value. Open up TreeGridNode.cs and change this line from internal to public:

           internal bool IsExpanded;


           public bool IsExpanded;

    Note that you don't want to publically set IsExpanded to true but instead use the Expand() method.


  234. Zena says:

    Hi Mark,

    Thanks for your excellent code. It helps me a lot but I have some problems, I am quite new in C#.

    I have several questions, I hope that you can help me again.

    1. There is no node .selectednode, but I also cannot remove the row, it will give me error. so Is there anyway to delete a node or a row?

    2. How to expand a particular node?

    3. How to expand and collapse all the nodes using code?



  235. Hi Mark, This is a great Control. Thanks for it. when i am using this i have a prblem in binding data to ComboboxColumn.  

    First colulmn is a Textbox and second is comboboxcolumn. Each Combobox will have different list based on Textbox Value.

    How we can acheive this? Which Event



  236. Set Edit mode to on enter:

    [your_instance_name].EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter;


  237. DataGridViewCell set style padding is very slow says:

    The call to TreeGridCell.UpdateStyle() is very slow and with a grid with 150 rows it take 10s to display the grid. It's very very long, how i can optimize this ?