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: https://www.windowsforms.net/blogs/markrideout/treegridview.zip
Here is a picture:
Anyway. The basic part of creating a DataGridView that can expand and collapse is to dynamically add and remove rows. That was the easy part. To make this really usable and extendable, I decided to add a lot code and make this easier to use. Here are some details:
Design
I wanted to ensure that the design of the TreeGridView supported normal TreeView type properties and features, so creating necessary classes to create the “tree view” experience wa necessary (see object model for more details).
Custom Painting – Painting an image in a cell is easy, but ensuring that the text from the DataGridViewTextBoxCell didn’t overlap the image took a bit of work. Using the Padding feature of the DataGridViewCellStyle, I add padding to the left side of the cell to account for the text and the indentation. This padding affects the painting and behavior of the text box cell, so editing a text cell correctly positions the editing control.
Siting/Unsiting a node – Since I don’t want to set padding and styling except when a node is actually displayed. When the node is displayed or in the grid, it is sited. When the node is sited I set all the necessary properties.
Unbound – Since expanding and collapsing is based upon dynamically adding and removing rows from the grid, I decided that unbound mode would be the best way to go with this. I’ve hidden the “databinding” properties and the virtual mode property since this doesn’t support those features.
Edit Mode – One thing that I had to deal with is that double-clicking a cell enters edit mode. This double-click occurs regardless of the padding, so double-click on the +\- symbol causes the control to enter edit mode. Edit also enters if you single click on a cell that already has focus. So, to deal with this I turn edit mode to be enabled only through programmatic means. I have code to handle the F2 key to enter edit mode. There are other ways to solve this, but I went with the F2 approach.
Object model structure
TreeGridNode - Just like a tree view, I wanted to have the concept of a node. I made the nodes class derive from a DataGridViewRow since a node in the list is the same as a row, just with a bit more info.
Here are some properties:
Nodes – Again, like the treeview, a node has children, so there is a Nodes property that returns child nodes. One of the challenges in coding this is to know when a node is actually a row or when it is just a node. A node is a row when it is in the grid, otherwise it is just a node.
IsSited – A node is “sited” when it is contained in the grid as a row. The Sited property is true in this case. There are a set of protected virtual methods on the TreeGridView class (SiteNode and UnSiteNode).
ImageIndex – Image index for the node’s image. Only used when an ImageList is associated with the TreeGridView.
Image – Image associated with the node. Sets or gets the image. When an ImageList is associated with the TreeGridView and an ImageIndex is set then this returns an image from the ImageList. You can set the Image property to an image if you aren’t using an ImageList.
Cells – Returns the cells for the given node. This wasn’t easy to do since accessing the cells for a node (or row) when the node isn’t sited. Using the DataGridView’s CreateCells method I can get the correct cells collection when the node isn’t in the grid.
TreeGridCell/Column – This is a special DataGridView cell that derives from the DataGridViewTextBoxCell. The main thing that this custom cell class does is to customize the cell drawing to make it look like a tree node. That means that it draws the node’s image and the +/- icons and the tree lines. The custom cell also is where a node detects when you click the mouse to expand or collapse a node. NOTE: A lot more work can be done to correctly detect that the mouse is directly over the +/- image. Right now I’m not doing that.
TreeGridView – This class derives from the DataGridView control. Many things are done in this class. Nodes are sited/unsited in the grid as actual rows. Somce DataGridView Properties are hidden since they do not apply.
Here are some properties:
VirtualNodes – One of the common things done with a normal TreeView is to dynamically add child nodes when the user is expanding the parent. With the normal TreeView usres add temp child nodes to get the + sign and support expanding, then remove the temp node later. With the VirtualNodes property, the TreeGridView always displays a + sign next to a node, even if the node doesn’t have any children. Then, by handling the Expanding event you can dynamically add child nodes.
ImageList – ImageList associated with the TreeGridView
Nodes – Identifies the root nodes.
ShowLines – Determines if the TreeGridView shows lines between nodes.
CurrentNode – Identifies the node that has focus.
Here are some events:
Expanding – Again, like the treeview, this event occurs before a node is starting to expand. You can add nodes in this event to fill in more details of a child node collection. When the VirtualNodes property is true, the TreeGridView will display the node with a + sign next to it even when it doesn’t have any children. Handling the Expanding event is where you would dynamically add new child nodes.
Expanded – After a node is expanded.
Collapsing – Before a node is being collapsed
Collapsed – After a node has been collapsed.
I’ve included a simple test app that creates a news group reader looking list that supports expanding and collapsing.
Let me know what you think and how you've used this in your project!
-mark
Comments
Anonymous
January 08, 2006
The comment has been removedAnonymous
January 08, 2006
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?
-amitchatAnonymous
January 09, 2006
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.Anonymous
January 09, 2006
Thanks for your sharing.It is quite good.
Ah.. I got errors and I can't compile and reuse.
My VS version is professional version.Framework version is 2.0.50727
Can you help me?
regards
ZawAnonymous
January 10, 2006
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!Anonymous
January 13, 2006
To be honest, i just started looking to build a similar functionality today in one of our projects and here u go such a brilliant tip. Would let u updated how well did i manage.
Cheers!!
A...Anonymous
January 13, 2006
i got errorsAnonymous
January 17, 2006
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!Anonymous
January 19, 2006
Very nice and usefull!Anonymous
February 01, 2006
Great works, thanks for sharing!Anonymous
February 01, 2006
DID this Support DRAG & DROPAnonymous
February 01, 2006
The comment has been removedAnonymous
February 01, 2006
TreeGridViewAnonymous
February 07, 2006
I want to move focus to next cell. I am using DataGridView control for DataEntry. So, When user done with editing particular cell and press enter, focus should go on to the next cell (not next row). How could I do this? please help me.. I am looking for this from last 10 days. Not got the solution yet. My email id is: logan@fissionvector.comAnonymous
February 07, 2006
Thanks a lot for the code.
I could include and utilize it by replacing TreeView control with this.
It was very useful for me.Anonymous
February 10, 2006
Looks wery good, but can I set focus to a special row? The "SelectedRows"is ReadOnly...Anonymous
February 13, 2006
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.Anonymous
February 13, 2006
The comment has been removedAnonymous
February 21, 2006
how to bind using dataset?Anonymous
February 23, 2006
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? thankyouAnonymous
February 26, 2006
Your treegridview have bug if VisualStyle is not enabled on your windows.
Can you fix it? I really need your code. Thanks your codeAnonymous
February 27, 2006
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.Anonymous
March 17, 2006
Niiice control.
Consider enablin' databindin'.
One of other cons - not workin' w/o VisualStyles. Here is the fixxx:
in "TreeGridView.cs" delete the followin' two lines:
------8<------
internal VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
internal VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
------8<------
in "TreeGridCell.cs" find the line "if (node.HasChildren || node._grid.VirtualNodes)" and change it so that it looks like that:
------8<------
if (node.HasChildren || node._grid.VirtualNodes)
{
// Ensure that visual styles are supported.
if (Application.RenderWithVisualStyles)
{
VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
// Paint node glyphs
if (node.IsExpanded)
//node._grid.rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
else
//node._grid.rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10));
}
else
{
int h = 8;
int w = 8;
int x = glyphRect.X;
int y = glyphRect.Y + (glyphRect.Height / 2) - 4;
//MessageBox.Show("x = " + x.ToString() + ", y= " + y.ToString());
graphics.DrawRectangle(new Pen(SystemBrushes.ControlDark), x, y, w, h);
graphics.FillRectangle(new SolidBrush(Color.White), x + 1, y + 1, w - 1, h - 1);
graphics.DrawLine(new Pen(new SolidBrush(Color.Black)), x + 2, y + 4, x + w - 2, y + 4);
if (!node.IsExpanded)
graphics.DrawLine(new Pen(new SolidBrush(Color.Black)), x + 4, y + 2, x + 4, y + h - 2);
}
}
------8<------
haha!Anonymous
March 28, 2006
I really like the News Reader GUI look! EXACTLY what I want for my hierarchical task list application.
However, as the previous post, the only 'thing' that's missing is the data binding... But, the good thing is that its not that much work to make it happen...
I'm thinking of doing this myself, if it's not "too late" - someone else has done that already...?
Thanks!Anonymous
April 04, 2006
Beautiful. Move it to SourceForge (or somewhere)!Anonymous
April 07, 2006
The comment has been removedAnonymous
April 18, 2006
Mark, I really like your control, but what I am trying to accomplish I am finding rather difficult with any of the grids at my disposal, nor am I able to find a clean solution. I am able to use the DataGridView and the C1FlexGrid, I am unable to purchase any others based upon budgetary constraints. I am hoping you can help with a suggestion or where a free control that can accomplish my needs.
The Issue:
I need to display a complex hierarchy of differentiating data in multiple stepped grids. Here is the hierarchy :
Order
----GRID:LineItem(s)
--------GRID:LineItem Price Assignment(s) (discounts, specials, etc.)
--------GRID:LineItem Option(s)
------------GRID:Option Price Assignment(s) (discounts, specials, etc.)
Each one of these grids has different columns, and data. I do not really want to use the standard - seperate grids to display the master - detail data. I would prefer if this was treed somehow.Anonymous
April 19, 2006
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.Anonymous
April 25, 2006
The comment has been removedAnonymous
April 26, 2006
You Rock!!! So great to have people that contribute like this.
Thanks!Anonymous
April 27, 2006
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? ThanksAnonymous
April 28, 2006
I've been enjoying the control, but I'm having trouble getting it to scale well. Having a node with anything more than 20 children quickly becomes unusable (50 nodes takes over 10 seconds to expand). It seems to come down to setting the this.Style.Padding on each cell, instead of using the default. Am I missing something or is creating a style for each cell really expensive?
Thanks.Anonymous
May 03, 2006
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.Anonymous
May 23, 2006
this is really cool.but adding databinding property would be perfect.if anybody had made this, please show the code:) i really need it.Anonymous
May 24, 2006
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?Anonymous
May 28, 2006
it is a great code.....is there any way to put check boxes instead of text boxes....I need something like : check Parent node...check all child nodes....Anonymous
June 07, 2006
The comment has been removedAnonymous
June 14, 2006
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?Anonymous
June 19, 2006
Your article is prety nice. It's a pity that i didn't see it more later.Anonymous
June 20, 2006
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...Anonymous
June 26, 2006
I need databinding, may be i make this.
Vary thanks for the this control !
Best regards to autor !Anonymous
August 01, 2006
The tree is expanded.
how do I get the current node?
I need to get the values on the click or double click...Anonymous
August 01, 2006
Mark,
How can I toggle the highlighting on a row with every mouse click?
I tried to override SetSelectedRowCore with no luck.Anonymous
August 19, 2006
thanks for code.
but,i hope VB sourceAnonymous
September 03, 2006
The comment has been removedAnonymous
September 04, 2006
Good work!
Can I have it in 2003 version?
Thanks.Anonymous
September 06, 2006
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 nullAnonymous
September 08, 2006
The comment has been removedAnonymous
September 16, 2006
Very nice. What about databinding, did anybody made it?Anonymous
September 25, 2006
First of all, Great job.
I'm tring to implement sort, I've though about using the
level of a node and the SortCompare event (only values with the same level will be sorted), my question is, how can I get the node of a row from the RowIndex property?
thanks...Anonymous
October 27, 2006
Hi, Who solved the error : Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'AdvancedDataGridView.TreeGridCell'. Thank youAnonymous
November 06, 2006
Hi, Is it possible to create a custom datagrid with the feature of expandable columns like expandable rows? Using that a user can expand and collapse the columns to edit the data. I am searching this for a long time. Please give me your valuable feedback. Thanks, NatrajAnonymous
November 07, 2006
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"Anonymous
November 14, 2006
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?Anonymous
November 23, 2006
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.Anonymous
November 27, 2006
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 JustifiedAnonymous
December 18, 2006
I wanted to use the control in windows 2000, without the XP Visual Styles, so I made some changes, based on another project I found here: http://www.codeproject.com/cs/miscctrl/XPCollapsGroupBox.asp The changes are: In the TreeGridView.cs instead of the 2 rows: internal VisualStyleRenderer rOpen = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened); //internal VisualStyleRenderer rClosed = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed); I have: internal Graphics rOpen ; internal Graphics rClosed ; In the TreeGridCell.cs Instead of : // Paint node glyphs if (node.IsExpanded) node._grid.rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10)); else node._grid.rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10)); I have: // Paint node glyphs if (node.IsExpanded) { node._grid.rOpen = graphics; node._grid.rOpen.DrawImage(Properties.Resources.minus, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10)); } else { node._grid.rClosed = graphics; node._grid.rClosed.DrawImage(Properties.Resources.plus, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10)); } For the last code snippet I added 2 images to the project resources. The images could be found in the project I mentions its url in the beginning.Anonymous
December 25, 2006
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 ?Anonymous
January 07, 2007
I've mananged to get a datagridview working very well with grouping as well as expanding and collapsing icons in the grid. The grouping has a category as the parent and descriptions... price... etc... as children with an item count in the Parent. Looks like this sort of in the DataGridView: Some Category (Plus Item Count) Descritpion Price Sold Some Category #2 (Plus Item Count) Descritpion Price Sold etc... It also has all the trimings with row delete... notes addition from a currentcell doubleclick which i'd be happy to share if anyone is interested. I have been trying to implement a DragDrop and having major trouble maintaining the above group when I move the rows in the DataGridView. I need to keep the Parent/Children relationship when the rows are moved in the DataGridView. Has anyone done this before that can offer the right way to go about solving the above? Have sample code to illustrate??? Any help would be greatly appreciated... Thank you in advance. Thanks, BillBAnonymous
January 18, 2007
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)Anonymous
February 01, 2007
I get a Error, using: Remove() (for sub Items) After used the method "Remove", I can not use the Expand() method.Anonymous
February 01, 2007
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!!Anonymous
February 03, 2007
Hi Mark, could you please tell me why did you choose to dyanmically insert/Remove a row for expand/collpase instead of setting it's visible property to true/false. Regards, ChintanAnonymous
February 06, 2007
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, -markAnonymous
February 22, 2007
I want to move focus to next cell. I am using DataGridView control for DataEntry. So, When user done with editing particular cell and press enter, focus should go on to the next cell (not next row). How could I do this? please help me.. I am looking for this from last 10 days. Not got the solution yet. My email id : vdp_30@yahoo.comAnonymous
March 19, 2007
Great site! Good luck to it's owner!Anonymous
April 11, 2007
Really a wonderful job. One Query.Can i add images in the third column.If yes then howAnonymous
April 24, 2007
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?Anonymous
April 25, 2007
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.Anonymous
May 02, 2007
I am curious if anyone is trying to use this on a .NET form that is accessed VIA Interop. I am asking because i am running into some threading issues and was maybe looking for some help. Thanks!Anonymous
May 09, 2007
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?thanksAnonymous
May 11, 2007
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. , ShashankAnonymous
May 16, 2007
Trying to get this to work in Compact Framework. Initially, I've had no success. Any ideas? Thanks. CHAnonymous
May 16, 2007
Hi All, DataGridView - Please Help I want to move focus to next cell in DataGridView control, as when user done with editing particular cell and press enter, focus should go on to the next cell (not next row). How could I do this? please help me.. my email is faisalbilwani@hotmail.comAnonymous
May 17, 2007
hi, i love the idea of treegridview has been implemented here. I wanted to know if u have this treegridview sample example in asp.net using C#. If u donot then could u post some url where i could get sample example of treegridview in asp.net Thanks...Anonymous
May 21, 2007
Hi, Mark. This is a very nice control that you have developed. But can you tell me how can i use your control in ASP.net 2.0. If this control can not be used in ASP.net,can you please tell where can i find the same with ASP.net support.Anonymous
May 27, 2007
Hi, thanks for your excellent effort for enabling the gridview for such a great functionality.Anonymous
June 13, 2007
Hi mark, This is very useful for me and my team. great work! Thanks for sharing this code and open my eye to view such property in Data Grid View. Karthik.CAnonymous
June 22, 2007
I also noticed the problem that when inserting a new node, it is always the last one. Does anyoone have a solution?Anonymous
July 11, 2007
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 alotAnonymous
July 13, 2007
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!Anonymous
July 13, 2007
Did anyone figure out a way to do databinding? Please share your ideas.Anonymous
July 16, 2007
Hi I'd like not to use images, i removed treeGridView1.ImageList fully but still have white squares after them, how to get rid of it?Anonymous
July 23, 2007
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?Anonymous
August 07, 2007
The comment has been removedAnonymous
August 10, 2007
Hi, Do you have vb version? It looks great. That is exactly what I want. tsueng@yahoo.comAnonymous
September 09, 2007
Hi, Can u pls tell me that how can i change code so that my TreeGridView control enable Drag and Drop facility?? I Mean to say that in typical TreeView , we can bind ItemDrag event and this Event further make a call to DoDragDrop() function. Here How can i call DoDragDrop function? ThanksAnonymous
September 11, 2007
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 !!Anonymous
September 13, 2007
How do I get the currently selected Node?Anonymous
September 20, 2007
How can I set focus to a special row? Please help.....Anonymous
October 02, 2007
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? ThanksAnonymous
October 08, 2007
great work! But, I'm curious why you didn't just use a treeview/listview combination (like Windows Explorer)?Anonymous
October 09, 2007
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. ;)Anonymous
October 15, 2007
"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.Anonymous
November 07, 2007
PingBack from http://blog.charlescarroll.com/chazblog/?p=501Anonymous
November 12, 2007
Hi I want Column where in that column cells i can put text as well as image on right corner of cell ThanksAnonymous
November 12, 2007
Hi I want Column where in that column cells i can put text as well as image on right corner of cell ThanksAnonymous
November 13, 2007
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.Anonymous
November 13, 2007
The comment has been removedAnonymous
November 13, 2007
awesome dude very impressed with this stuff helped us so much n1Anonymous
November 23, 2007
Hey Mark, Josh from missouri. I know this blog isn't for personal stuff, but I don't have your other contact info anymore. I hope you're doing well. Contact back if you like. joshhurlahee@hotmail.comAnonymous
December 03, 2007
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.Anonymous
December 04, 2007
Man, you are a star. Just what I've been looking for! Thanks a million.Anonymous
December 07, 2007
Hi, Im trying to include your code in my application. The only thing Ive modified is to remove the attachemnt column to reduce the number of columns to 3. However, each time I want to add a node, The Cells.Count always return 0 instead of 3. Im developing my app under Linux. Any idea of what might go wrong? Thank youAnonymous
January 08, 2008
Hi, it is a very nice code, and it's something I was looking for. But it has some bad sides. one is this; code: AdvancedDataGridView.TreeGridColumn treeColumn = new AdvancedDataGridView.TreeGridColumn(); treeGridView1.Columns.Add(treeColumn); treeGridView1.Columns.Add("first", "first"); treeGridView1.Columns.Add("second", "second"); AdvancedDataGridView.TreeGridNode node = new AdvancedDataGridView.TreeGridNode(); AdvancedDataGridView.TreeGridNode node2 = treeGridView1.Nodes.Add("x", "x", "xx"); treeGridView1.Nodes.Add(node); node.SetValues("1", "A", "B"); node = new AdvancedDataGridView.TreeGridNode(); node.SetValues("3", "aaA", "bbB"); //not visible node2.Nodes.Add(node); node.Nodes.Add("y", "y", "y"); node = new AdvancedDataGridView.TreeGridNode(); treeGridView1.Nodes.Add(node); node.SetValues("4", "aaaA", "bbbB"); end code a very simple code, but the node marked not visible will be empty in the grid....strange... also strange that if you fill the node with data before adding it to the treeGridView (or another node) it will be still empty. I am trying to use this for my monitoring app. I'll be back with my resultsAnonymous
January 13, 2008
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....Anonymous
January 30, 2008
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. fiAnonymous
February 02, 2008
Hi, i tried to get the source, but, its not there anymore.. am i too late?Anonymous
February 19, 2008
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.Anonymous
March 12, 2008
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.Anonymous
March 17, 2008
I, as well, was curious if anyone has successfully ported the source code to VB.NET? I am using the express edition of Visual Basic, so having different parts of my application in different languages does not make the most sense. Anyone?Anonymous
March 31, 2008
Hi Mark, Thanks for the nice post. I am new to C# as well as DataGridView. Could you please help me in extending DataGridView that contains another DataGridView in one of it's columns. I don't want the user of my application to edit data. Kindly help me to solve my problem. Thanks and Regards, ManiX mail2manix [at] gmail [dot] comAnonymous
April 02, 2008
The comment has been removedAnonymous
April 14, 2008
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).Anonymous
April 17, 2008
Can we display checkboxes in tree ??? if yes then how plz reply thanks imran saeed email: imransaeed@my.web.pkAnonymous
May 11, 2008
Hi Mark, This is very useful. How do we do for DataTable/DataView as DataSource? Something like : OrderNumber:0001 ItemNumber ItemQty OrderNumber:0002 ItemNumber ItemQtyAnonymous
May 15, 2008
hello, it's a very nice code. do you have it for vb.net? C# is unknow for me.... thanks,Anonymous
May 16, 2008
The comment has been removedAnonymous
May 21, 2008
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..Anonymous
June 05, 2008
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 youAnonymous
June 12, 2008
Given a row index, how can I find the node associated with what is displayed in that row? It does not appear to be trivial unless I am missing something obvious... Is there a helper function for this? Thanks -GAnonymous
June 16, 2008
Brilliant control! Thank you Mark!Anonymous
June 23, 2008
Hi I did the data binding successfully but i dnt know how to save that data in database like parent node's data separately and child node's data separately.Anonymous
June 29, 2008
Sort columns: private void treeGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex < 0) { foreach(TreeGridNode node in this.treeGridView1 .Nodes) { node.Collapse(); } ListSortDirection direction = new ListSortDirection(); if (this.treeGridView1.SortOrder == SortOrder .Ascending ) direction = ListSortDirection.Descending ; else direction = ListSortDirection .Ascending ; this.treeGridView1.Sort(this.treeGridView1.Columns[e.ColumnIndex ], direction); } }Anonymous
July 09, 2008
Has anyone found a solution to the slow recursive expanding node problem yet?Anonymous
August 12, 2008
Hi Mister.... this grid.. is very good... thanks!!! .... MarcoAnonymous
August 13, 2008
Don't know what to say. Please accept my millions thanks.Anonymous
August 15, 2008
Hello, nice control. thanks!!! JM www.pronexo.comAnonymous
August 20, 2008
I am trying to use your control in my application and in process of evaluating that control found that when using about 200 subnodes in root node, the time to expand that node is about 6 sec, but if I will try to expand similiar second node with also 200 subnodes and not collapsing first one, it will take almost double time, when trying to expand third node with 200 subnodes, it will take almost tripple time and so on. Is it something with control or with the way I am trying to add nodes. Any response will be appriciated. Thanks, PeterAnonymous
September 01, 2008
to expand and collapse all nodes add this code to TreeGridView class [Description("Expands all nodes")] public void ExpandAll() { foreach (TreeGridNode node in this.Nodes) { expandNode(node); } } private void expandNode(TreeGridNode node) { if (node.Nodes.Count > 0) { node.Expand(); foreach (TreeGridNode subNode in node.Nodes) { expandNode(subNode); } } } [Description("Collapse all nodes")] public void CollapseAll() { foreach (TreeGridNode node in this.Nodes) { collapseNode(node); } } private void collapseNode(TreeGridNode node) { if (node.Nodes.Count > 0) { foreach (TreeGridNode subNode in node.Nodes) { collapseNode(subNode); } node.Collapse(); } } ps recursion rocksAnonymous
September 04, 2008
The comment has been removedAnonymous
September 07, 2008
Plz someone convert it to vb version please....Anonymous
September 08, 2008
good idea for Expand/CollapseAll, but i would place the collapseNode method into TreeGridNode: TreeGridView.cs: /// <summary> /// Expands all nodes. /// </summary> [Description("Expands all nodes")] public void ExpandAll() { foreach (TreeGridNode node in Nodes) node.ExpandAll(); } /// <summary> /// Collapses all nodes. /// </summary> [Description("Collapses all nodes")] public void CollapseAll() { foreach (TreeGridNode node in Nodes) node.CollapseAll(); } and TreeGridNode.cs: /// <summary> /// Collapses all nodes and all child nodes recursively. /// </summary> public void CollapseAll() { if (Nodes.Count > 0) { foreach (TreeGridNode subNode in Nodes) subNode.CollapseAll(); Collapse(); } } /// <summary> /// Expands this node and all child nodes recursively. /// </summary> public void ExpandAll() { if (Nodes.Count > 0) { Expand(); foreach (TreeGridNode subNode in Nodes) subNode.ExpandAll(); } }Anonymous
September 16, 2008
Gary, To use this with VB.NET, just compile it into a class library (dll) and add it as a reference to your project.Anonymous
September 16, 2008
Marcelo, Try reading Spoook's post. Then, use that code.Anonymous
October 23, 2008
How can we allow the user to add rows? or modify some row? ..Anonymous
October 28, 2008
Hi, To begin, thank you for this custom control. I use it more and more to overcome the limitations and delays of the classical listview. However, I meet a problem of memory usage. I must show a treegridview with approximately 2000 rows, and 50 columns. When I create that rows for the first time, all is ok. To win speed display, when I create rows, I make my columns invisible, and after the process of creation, I make my columns visible. It saves a lot of time to create/show the rows. The problem comes when I want to refresh my informations list. I delete all my rows, and I recreate them. The problem is that "Rows.Clear()" does not release memory. For each refresh, the process takes more time. And when I try to close the window control (after the first refresh), it freezes. I tried some functions of control, without success ! Are you've encountered the problem ? Can you help me ? In advance thank you. EricAnonymous
October 28, 2008
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.Anonymous
November 13, 2008
@nerix just try it for several times, to write and afterwards delete the contents of the grid and look at the task manager memory consumption. You will see that after several cycles the memory gets released. I use the following command: treeGridView1.Nodes.Clear(); As I said, I tried it for 20 write/delete cycles with a grid consisting of 5000 nodes with 5 subnodes each and it seems to work. The bandwidth of memory consumption is about 200 Mb. @all Also, if acceptable, set treeGridView1.Visible = false; at the beginning of the loading process and at the end back to true. It seems indeed to speed up a lot the loading. I also use a secondary thread to fetch the data and delegate periodically the writing to the ui thread to load it. From the UI thread: System.Threading.Thread t = new System.Threading.Thread(SqlReadData); t.IsBackground = true; t.Start(); The delegate: private delegate void UpdateDelegate(string[] d); In the background thread: ... fetch the data... string[] str = new string[5]; str[0] = MyReader.GetString(0); str[1] = MyReader.GetString(1); str[2] = MyReader.GetString(2); str[3] = MyReader.GetString(3); str[4] = MyReader.GetString(4); this.Invoke(new UpdateDelegate(UpdateLabel), new Object[] { str }); Also, all about 100 nodes : cnt++; if (cnt % 100 == 0) { Thread.Sleep(0); } I know, I know, quick and dirty, but it helps to unfreeze the UI thread. Then back in the main thread (UI = user interface), the delegate function: private void UpdateLabel(string[] dataline) { Font boldFont = new Font (treeGridView1.DefaultCellStyle.Font, FontStyle.Bold); AdvancedDataGridView.TreeGridNode node; node = treeGridView1.Nodes.Add (null, "sometext", "tab", @"10/19/2005 1:02 AM"); node.ImageIndex = 0; node.DefaultCellStyle.Font = boldFont; node = node.Nodes.Add(null, " " + dataline[0], dataline[1], dataline[2], dataline[3], dataline[4]); for (uint h = 0; h < 5; h++) node = node.Parent.Nodes.Add(null, " " + dataline[0], dataline[1], dataline[2], dataline[3], dataline[4]); } I also have to say that my grid is usually loaded once, at the beginning, with normally no further large modifications (maybe some append for few nodes). Regards, RaduAnonymous
November 25, 2008
树形结构的DataGridView:CustomizingtheDataGridViewtosupportexpanding/collapsing(alaTreeGridView)Anonymous
November 28, 2008
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. ThanksAnonymous
November 30, 2008
Someone who has solved insert CheckBox control yeat?Anonymous
December 09, 2008
@jerrydusing The TreeGridNode caches its index, but doesn't update the cached value when a node is removed. My fix was to ALWAYS calculate the index instead of using the cached version TreeGridNode: public new int Index { get { _index = this._owner.IndexOf(this); return _index; } } Hope that helps! TimAnonymous
December 10, 2008
If you are interested, I've modified the TreeGridView in order to support DataSource with hierachical data in it (id, parent id). This is the link: http://www.advancedcomputing.ch/Blog/tabid/73/Default.aspx AngelAnonymous
December 11, 2008
In my last post, I have highlighted problem with deleting nodes. I have found the bug. When a node is deleted, the sibling nodes after the deleted node must be reindexed. Because RowIndex is computed using the node index. To correct this bug, in TreeGridNode.cs you have to add the following method: //JD's Note: // all child nodes have to be reindexed when // an intermediate node is removed, because // when this node is resited, its position // is computed based on its node index. // internal protected void ReIndex( TreeGridNode node ) { for (int i = this.Nodes.Count-1; i > node.Index ; i-- ) { this.Nodes[i].Index = i-1; } } The above method has to be called from the RemoveChildNode method. The edit method is as follows: internal protected virtual bool RemoveChildNode( TreeGridNode node ) { if ((this.IsRoot || this._isSited) && this.IsExpanded ) { //We only unsite out child node if we are sited //and expanded. this._grid.UnSiteNode(node); } node._grid = null; node._parent = null; node._level = -1; //JD's Note: // The node has to be reindexed so that it will // be sitedin the correct position within // the TreeGridView. this.ReIndex(node); return true; } I trust that help some of you who had a bit of problem with node deletion.Anonymous
December 16, 2008
I've started to enhance the TreeGridView from Mark Rideout's blog Now I've quite finished the work:
- Krypton layout and color schemes support (from Computerfactory.com)
- datasource support
- grouping by specific column
- true hierarchical display of data (using id and parentid column names, id = parentid for parent nodes)
- grouping level blocked on the first level (not for hierarchical)
- custom parent and childs images
- ... check my site for code: http://www.advancedcomputing.ch/ Regards /// Angel
Anonymous
December 17, 2008
Hi Mark: Just to mention a mistake that I have to use your control .. I'm using W2000 without VisualStyle .. I come with an administrator account and there is no problem ... but if I enter as a normal user .. want to display the control I was a mistake. I have concluded that the privileges of the account. Why? Thanks for your help and your valuable time luisalberto_aguilar@hotmail.comAnonymous
December 17, 2008
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 timeAnonymous
December 26, 2008
Hi, We have a checkbox column and I was trying to read all checked rows and it seems that I was not able to read collapsed rows data. any one has any workarounds for this. ex: node["column1"].value says that column with name "Column1" can not be found it works fine if I expand the nodes and tried to read it. anythoughts over it???Anonymous
January 06, 2009
Hi Mark Excellent code. That's greatAnonymous
January 08, 2009
Hi Mark, First off, great job. This control has saved me a lot of time. In our application we have some cases when a node is expanded to show around 350 child nodes, which is very slow. It takes around a minute to add them to the grid. I'm saying "add them" and not "show them" because in the first moment we only retrieve the parent nodes from the DB. Then if the user clicks on any plus sign the children are retrieved. I have checked that the method which gets the children takes only 1 second, so the problem occurs when adding them to the control. Has anyone else come across this issue? Thanks.Anonymous
January 15, 2009
Anyone have this control in VB.Net? Thanks.Anonymous
January 15, 2009
The comment has been removedAnonymous
January 16, 2009
The comment has been removedAnonymous
February 02, 2009
The comment has been removedAnonymous
February 03, 2009
The comment has been removedAnonymous
February 17, 2009
The comment has been removedAnonymous
February 17, 2009
Hi Mark: Congratulations it's an excellent code , thank you so muchAnonymous
March 02, 2009
Great contribution. Thank you very much.Anonymous
March 11, 2009
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.Anonymous
March 11, 2009
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.Anonymous
March 27, 2009
Hi Mark Your work is beyond appriciation. Its really really good. I am a new developer. I am trying to bind data from two tables (Master and Detail) into your control. Here a parent can have more than one child and a chid can also belong to more than one parent. I am not getting exactly how to do. Your help in this matter will be highly appreciated. my email address is koiralakk@yahoo.com. Thanks.Anonymous
March 31, 2009
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.Anonymous
April 08, 2009
hello sir, please help me in finding a solution to "redrawing of child nodes after deletion in Mark Rideout's TreeGridView". Whenever i try deleting a node,all the other nodes get displaced.This happens when there is only 1 child node to a parent. if you could atleast provide me the link to the latest version of TreeGridView,it would be of great help and i would be grateful to you. Thanks in advance. regards, Nafisa.Anonymous
April 23, 2009
Hi Mark, Thank you for this great control. As far as the slow performance caused by setting the Padding goes (thanks for identifing the problem Matthias!), one easy solution is to calculate the padding inside OnPaint(). This is what I did roughly: TreeGridCell.cs in function OnPaint(): replaced Rectangle glyphRect = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1); with _lastKnownGlyphRect = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1); and moved the call just before base.OnPaint(). Added cellStyle.Padding = new Padding(_lastKnownGlyphRect.Right+_imageWidth, 0, 0, 0); just before calling base.OnPaint(). Naturally, I hashed out setting this.Style.Padding at the end of UpdateStyle(). And I had to change OnMouseDown() and replace if (e.Location.X > this.InheritedStyle.Padding.Left) with if (e.Location.X > _lastKnownGlyphRect.Right || e.Location.X < _lastKnownGlyphRect.Left) Works much faster with larger number of elements now. :) Just be careful when using my code, I haven't tested it thoroughly yet. :PAnonymous
May 11, 2009
About inserting new rows..... Try in TreeGridView.cs in internal protected virtual void SiteNode(TreeGridNode node) in while (currentRow.Level >= node.Level) { ...... } take off "=" while (currentRow.Level >/=/ node.Level) { ...... } Hope this helps.Anonymous
May 22, 2009
I have written the code for sorting subnode..
In TreeGridNode add Public variable: ..... public int OrderValue = -1; public String OrderString = ""; .....
in TreeGridNodeCollection add new enum: public enum SortingType { Integer = 0, String = 1, none = 2, }
in TreeGridNodeCollection add new public void: public void CompareSorting(ListSortDirection Order, int StartIndex, SortingType type) { this._owner._grid.SuspendLayout(); bool hadChildren = this._owner.HasChildren; bool IsExpand = this._owner.IsExpanded; this._owner.Collapse(); switch (type) { case SortingType.Integer: this._list.Sort(StartIndex, (this._list.Count - StartIndex), new CompareItem(SortingType.Integer, Order)); break; case SortingType.String: this._list.Sort(StartIndex, (this._list.Count - StartIndex), new CompareItem(SortingType.String, Order)); break; } foreach (TreeGridNode node in this._list) { node.Index = this._list.IndexOf(node); } if (IsExpand) { this._owner.Expand(); } if (!hadChildren && this._owner.IsSited) { this._owner._grid.InvalidateRow(this._owner.RowIndex); } this._owner._grid.ResumeLayout(); }
in TreeGridNodeCollection add new Class Comparer: private class CompareItem : IComparer<TreeGridNode> { internal ListSortDirection _direct; private CompareInfo _compareInfo; SortingType sortType; public CompareItem(SortingType xsortType, ListSortDirection xdirect) { _compareInfo = CultureInfo.CurrentCulture.CompareInfo; sortType = xsortType; _direct = xdirect; } public int Compares(TreeGridNode item1, TreeGridNode item2) { if (item1 == null || item2 == null || sortType == SortingType.none) return 0; switch (sortType) { case SortingType.Integer: { if (_direct == ListSortDirection.Ascending) { return item1.OrderValue.CompareTo(item2.OrderValue); } else { return item2.OrderValue.CompareTo(item1.OrderValue); } } case SortingType.String: if (_direct == ListSortDirection.Ascending) { return _compareInfo.Compare(item1.OrderString, item2.OrderString, CompareOptions.None); } else { return _compareInfo.Compare(item2.OrderString, item1.OrderString, CompareOptions.None); } default: return 0; } } public int Compare(TreeGridNode item1, TreeGridNode item2) { return Compares(item1 as TreeGridNode, item2 as TreeGridNode); } }
Use this code with: NODE.Nodes.CompareSorting(order, index, type) Regards, Fix978
Anonymous
June 14, 2009
Hello, I have problem with Insert a node in TreeGridView. The new node is always added in the last of list. Do you have any sample code for insert node with index? If you have please give me. Thanks, ThangAnonymous
June 24, 2009
The comment has been removedAnonymous
July 02, 2009
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.
Anonymous
July 16, 2009
The comment has been removedAnonymous
July 17, 2009
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); this.imageStrip.Images.AddStrip(Properties.Resources.newGroupPostIconStrip); 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);}}Anonymous
August 11, 2009
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(); tn.Nodes.Add("A"); tn.Nodes[0].Nodes.Add("A.1"); tn.Nodes[0].Nodes.Add("A.2"); treeView1.Nodes.Add(tn); treeGridView1.Nodes.Add(tn); //Will only add the first node </font></b>Anonymous
August 14, 2009
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!Anonymous
September 02, 2009
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. Regards, R SinghAnonymous
September 03, 2009
The comment has been removedAnonymous
September 13, 2009
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 [ ] Regards,Anonymous
September 16, 2009
The comment has been removedAnonymous
November 12, 2009
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; } else { 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; } else { 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 :).Anonymous
November 17, 2009
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.Remove(this); _oldParent.Nodes.Insert(--iIndex, this); _grid.CurrentCell = Cells[0]; } public void MoveDown() { int iIndex = RowIndex; TreeGridNode _oldParent = this.Parent; _oldParent.Nodes.Remove(this); _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.Anonymous
November 17, 2009
The comment has been removedAnonymous
November 18, 2009
Thanks Mark for the good work. Can you explain how to support allowing the user to add and delete rows?Anonymous
November 22, 2009
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.Anonymous
November 25, 2009
this is a very good article which binds datagridview just alike treeview, i like to use this feature in my site.Anonymous
November 27, 2009
Great contribution. Thank you very much. Anyone have this control in VB.Net? Thanks. cleomarcoelho@hotmail.comAnonymous
December 13, 2009
You are genious! Thanks for your sharing.Anonymous
December 14, 2009
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?Anonymous
December 15, 2009
The comment has been removedAnonymous
December 29, 2009
treegridview make ensurevisible and find node?Anonymous
January 03, 2010
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.Anonymous
January 04, 2010
Hi Mark, I want one sample application in which u have implemented this one.Please try to send to sayedaly@live.com. As its really helpful for me.Waiting for your mail Mark. Thanking U Sayed AliAnonymous
January 17, 2010
The comment has been removedAnonymous
January 19, 2010
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! ThanksAnonymous
March 08, 2010
Hi everyone! i want to ask if i can get editable cells with this control? Could someone convert this code to vb.net? Thanks.Anonymous
March 18, 2010
Very nice piece of work! These are the type of projects that are worth paying for! Kudos to the author!Anonymous
March 26, 2010
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.Anonymous
March 31, 2010
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) in 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) after //TODO: do we need to use index parameter? if ((this._isSited || this.IsRoot) && his.IsExpanded) this._grid.SiteNode(node); write this code //Reindexing... for (int i = index; i < this.Nodes.Count; i++) this.Nodes[i].Index = i; // In my project it works.Anonymous
April 04, 2010
Realy nice work man! Tnx a lot!Anonymous
April 09, 2010
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 NaiduAnonymous
April 28, 2010
Only two words. THE BEST ThanksAnonymous
May 10, 2010
The tree is expanded. how do I get the current node? I need to get the values on the click or double clicAnonymous
May 10, 2010
I need to get the values on the click or double click... HasChildren...IsParent doesnt work... Please helpAnonymous
May 10, 2010
Can i get the selected node in the selected row. Need to add code to display context menu...Please help... ThanksAnonymous
June 04, 2010
How to select a TreeNode using Rows.Index?Anonymous
June 04, 2010
Hi Mark Felicidades!!! ;) how can I get the node of a row from the RowIndex property?Anonymous
June 08, 2010
The comment has been removedAnonymous
July 06, 2010
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 this.eventsTGV.Nodes.Clear(); // clear all data this.dates.Clear(); this.labels.Clear(); 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. ChrisAnonymous
July 19, 2010
The comment has been removedAnonymous
July 28, 2010
Any idea how can I use this control without Visual Styles enabled?Anonymous
August 14, 2010
This control looks very promising. My compliments on an excellent job.Anonymous
August 17, 2010
I am looking for an implementation of a DataGrid-TreeView hybrid. actually same idea like above but should be a DataGrid.Anonymous
August 23, 2010
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.Anonymous
August 23, 2010
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.Anonymous
August 23, 2010
The comment has been removedAnonymous
November 24, 2010
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 asp.net? i need design this example but in web application i really need help for this!!!Anonymous
December 06, 2010
The comment has been removedAnonymous
December 17, 2010
Hi, thanks for your code. That's what I really need now. It's awesome. :)Anonymous
December 27, 2010
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. Thanks, NaynaAnonymous
January 04, 2011
With regard to Visual Effects, check out the solution at: social.msdn.microsoft.com/.../b1167539-1f93-4d30-87cd-04f25626e78dAnonymous
March 01, 2011
How i can know what item is selected in the treeview column? ThanksAnonymous
March 24, 2011
The comment has been removedAnonymous
May 29, 2011
Hey, 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 GeoffAnonymous
June 06, 2011
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.. shrusharan@gmail.com.. Thanks in advanceAnonymous
June 07, 2011
The comment has been removedAnonymous
June 15, 2011
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. this._grid.UnSiteNode(node); } //Reindexing... 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; }Anonymous
August 13, 2011
The comment has been removedAnonymous
April 01, 2012
Thanks!!Now I have make my own gridview similar to you and its working!!!Nice Work!Anonymous
May 21, 2012
Incredible work!!! congrats... now is it possible to add checkmarks to the tree? That would make this control a killing one!Anonymous
June 25, 2012
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 youAnonymous
July 18, 2012
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; } } }Anonymous
March 20, 2013
The comment has been removedAnonymous
March 20, 2013
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.Anonymous
May 01, 2013
Hi Mark, How can I check if a node is expended? Is there a IsExpanded property available? Thanks.Anonymous
May 06, 2013
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.Anonymous
May 08, 2013
The comment has been removedAnonymous
May 13, 2013
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.
- 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?
- How to expand a particular node?
- How to expand and collapse all the nodes using code? Regards, Zena
Anonymous
July 26, 2013
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 Thanks RajAnonymous
October 15, 2013
Set Edit mode to on enter: [your_instance_name].EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter; Cheers!Anonymous
December 05, 2013
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 ? Regards; Gilles