TreeView with Columns

TreeView with Columns

20 Feb 2008
TreeView with Columns and (partially) Design Time support

Is your email address OK? You are signed up for our newsletters but your email address is either unconfirmed, or has not been reconfirmed in a long time. Please click here to have a confirmation email sent so we can confirm your email address and start sending you newsletters again. Alternatively, you can update your subscriptions.

test_tree_validation.pngtest_tree_folderview.png

TreeView with Columns and (partially) Design Time Support

I have written several custom controls over the last couple of years, some of the controls were written from scratch, and others were enhancements to existing (3rd party) controls. What was common for all of the controls was that I didn’t pay any attention to how to implement design time support.
Since the standard Microsoft .NET TreeView does not support columns, I decided it would be a useful and fun project to write a tree control that supports columns from scratch, and at the same time I could learn about the design time side of writing custom controls.
The tree supports:

  • Columns, fixed sized and auto sized. Can be added at design time. Header and cell format and color can be set at design time.
  • Reorder visible columns, hide / show columns (programmatically only)
  • Image list and image index for nodes
  • Single / Multi select
  • Easy to overwrite cell paint
  • Build child nodes on demand

What is not supported (yet):

  • Sorting of columns
  • Cell edit
  • Re-arranging columns at run time
  • Individual row height. Only fixed row height is supported

Node and NodesCollection

Before implementing the node and node collection, I considered whether to use a list List<Node> for node collection, or to keep the nodes as a linked list. In my experience I have almost never had to access nodes by index directly, but rather through iteration. However, I have often had to remove and insert nodes before or after other nodes, so for this reason I decided on the linked list implementation.
Node and NodesCollection are implemented in TreeListNode.cs.

CommonTools.Node
CommonTools.NodeCollection

Implementing the Node and NodesCollection was for the most part straightforward. The node contains a Prev/Next pointer (linked list) and the NodesCollection contains a FirstNode LastNode and a count.

Performance Issues

A common approach when building large trees is to build the child nodes of a node only before the node is expanded for the first time. To support this and at the same time still show the node as having children, even when in fact it is empty, the property HasChildren was added. Now when a node is added to the tree, if HasChildren is set it will show the plus/minus sign and it is then the developers responsibility to fill in the child nodes on the callback event NotifyBeforeExpand or override OnNotifyBeforeExpand.
The FolderView tree is an example of building the child nodes on demand.
Another performance issue to consider when building a tree is how to get the total number of visible nodes. The GUI part of the tree needs to know how many rows are visible in order for it to adjust the vertical scrollbar. For instance, if there is one root node with 10 children and the node is collapsed the visible row count is 1, and when the node is expanded the visible row count now changes to 11. The slow approach to this is to iterate through all visible nodes, but clearly this is not ideal for a large tree.
The solution to this is to have each node notify its parent when the visible count changes, this way any change will propagate all the way up to the root collection and now access to VisibleNodeCount just returns the total visible count.
To verify that the count was correct, I added both VisibleNodeCount and slowTotalRowCount and I check the two values in a node validation when Validate is clicked on the “Tree Validation” tree.

Columns

There is not much to the TreeListColumn class. It contains formatting for the header and the cells, the caption and fieldname, the default size and the auto size mode.
The TreeListColumnCollection is a little more interesting. The collection contains a list of the columns in the order they have been added. This is used for accessing the data in the node by index and is the default implementation for the GUI’s GetData.

protected virtual object GetData(Node node, TreeListColumn column)
{
if (node[column.Index] != null)
return node[column.Index];
return null;
}

It also contains a list of the visible columns which is what is used when painting the tree. Whenever a column is resized or the tree is resized, the visible column’s rectangles are being recalculated. This is done in RecalcVisibleColumsRect.
The column has an AutoSize option. When this is enabled, the column cannot be resized. Instead the width of the column will be set to the minimum size set in AutoSizeMinSize plus a ratio of the remaining width. The ratio is found by adding up all the ratio values from the different AutoSize columns and then dividing it by the remaining width. An example of the auto size is AutoSize where the first column has a ratio of 100 and the second column has a ratio of 50, so the first column will get 2/3 of the remaining width while the second column will get 1/3.

Design Time Issues for ColumnsCollection

At first when I implemented the columns collection, it didn’t show the ellipses button (…) in the property grid, and no matter what I tried I couldn’t get it to show up. I found that if I derived from CollectionBase or List<TreeListColumn> then it would show. But if I implemented only IList<TreeListColumn> then it would not show.
The obvious solution would have been to derive from List<> and then override the APIS, but instead I decided to figure out why it didn’t work with the IList<> interface.
After doing some investigating using Reflector, I found that the default CollectionEditor depends on the IList interface, and sure enough List<> implements both IList<> and the IList interface. And once I added the IList interface to the collection, it showed up in the property grid.

ColumnCollectionEditor

To give the column a unique caption and fieldname when created, I created a new editor ColumnCollectionEditor derived from CollectionEditor, and then I assigned this editor to the collection class with the Editor attribute:

[Editor(typeof(ColumnCollectionEditor),typeof(System.Drawing.Design.UITypeEditor))]

The only customization I had to add to the editor was the following:

  • CreateInstance, which is called when Add is clicked in the designer. Here a new column is created with a unique fieldname.
  • GetDisplayText, this is the text shown in the list, I chose to show caption(fieldname) and keep it read only, and finally
  • EditValue, this is called after a value has changed. Here I refresh the tree to reflect changes in the GUI immediately.

“TreeView with Columns”의 38개의 댓글

  1. I think this is among the most significant info for me.

    And i am glad reading your article. But should remark on some general things, The
    web site style is ideal, the articles is really nice :
    D. Good job, cheers

  2. Hey there just wanted to give you a brief heads up and let you know a
    few of the pictures aren’t loading properly. I’m not sure why but I think its a linking issue.
    I’ve tried it in two different internet browsers and both show the
    same results.

  3. Hi there! This article couldn’t be written any better! Going through this article reminds
    me of my previous roommate! He continually kept talking about this.
    I most certainly will send this post to him. Fairly certain he’ll have a great read.
    Thanks for sharing!

  4. Howdy! This post could not be written much better!
    Going through this post reminds me of my previous
    roommate! He continually kept preaching about this. I will
    forward this post to him. Fairly certain he will have
    a very good read. Thank you for sharing!

  5. I just want to say I’m very new to blogs and absolutely loved your web page. Likely I’m want to bookmark your blog . You actually have terrific articles. Thanks a bunch for sharing with us your website page.

  6. Wonderful post. I discover something more tough on various blogs daily. It will constantly be boosting to read web content from various other writers as well as exercise a little something from their store. I?d like to make use of some with the web content on my blog whether you don?t mind. Natually I?ll give you a link on your internet blog. Thanks for sharing.

  7. And Im running from a standard users account with strict limitations, which I think may be the limiting factor, but Im running the cmd as the system I am currently working on.

  8. There are definitely a lot of information like that to take into account. That is an excellent indicate bring up. I use the ideas over as basic inspiration however plainly there are concerns like the one you bring up where the most important point will be working in honest good faith. I don?t understand if best methods have emerged around things like that, but I make certain that your task is clearly determined as a fair game. Both boys as well as ladies feel the effect of just a moment?s enjoyment, for the rest of their lives.

  9. I was extremely happy to discover this web-site. I intended to many thanks for your time for this fantastic read!! I definitely taking pleasure in every little bit of it and I have you bookmarked to check out brand-new things you post.

  10. You made some respectable factors there. I looked on the web for the issue and also discovered most individuals will go along with with your internet site.

  11. An intriguing discussion deserves comment. I assume that you must write much more on this subject, it may not be a taboo subject however usually individuals are not nearly enough to talk on such topics. To the next. Thanks

  12. Youre so awesome! I do not mean Ive read anything like this before. So good to locate someone with some original thoughts on this subject. realy thank you for beginning this up. this internet site is something that is required online, a person with a little originality. helpful job for bringing something brand-new to the net!

  13. There are some interesting moments in this short article however I don?t recognize if I see all of them center to heart. There is some legitimacy however I will certainly take hold point of view till I check into it additionally. Excellent short article, thanks as well as we want much more! Included in FeedBurner as well

  14. Aw, this was an actually great post. In concept I would like to place in composing like this furthermore? requiring time as well as actual effort to make a great short article? however what can I claim? I procrastinate alot and never seem to obtain something done.

  15. An outstanding share, I just provided this onto an associate who was doing a little evaluation on this. As well as he in fact bought me morning meal since I located it for him. smile. So let me reword that: Thnx for the reward! Yet yeah Thnkx for investing the moment to review this, I feel strongly regarding it as well as like learning more on this topic. Ideally, as you become experience, would you mind updating your blog with more information? It is extremely helpful for me. Big thumb up for this blog post!

  16. I?m pleased, I should claim. Actually seldom do I run into a blog that?s both informative as well as amusing, as well as let me tell you, you have actually struck the nail on the head. Your idea is outstanding; the concern is something that insufficient individuals are talking intelligently around. I am really happy that I came across this in my look for something associating with this.

  17. A remarkable share, I simply offered this onto a coworker who was doing a little analysis on this. And he in fact bought me breakfast since I located it for him. smile. So let me reword that: Thnx for the reward! But yeah Thnkx for investing the time to review this, I feel strongly concerning it and also enjoy finding out more on this topic. When possible, as you end up being expertise, would certainly you mind updating your blog site with even more details? It is extremely practical for me. Large thumb up for this article!

댓글 남기기