Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

TreeView with Controls (Supported Org Chart Style)

4.96/5 (20 votes)
19 Feb 2015CPOL3 min read 46.3K   2.3K  
CTreeView is the advanced TreeView control for .NET WinForms that supports more features, different layouts and any controls in the nodes.

Image 1

Introduction

Standard .NET TreeView control has poor functionality. Once I needed to put buttons into nodes, or even not only buttons, for example, buttons + check boxes + etc. There is no simple way to do it. I looked for existing solutions, but all of them provide restricted views of nodes. So, I created this custom control that may contain any WinForms controls in the nodes. Now I learned WPF and discovered that such things are much easier there, but I hope that my solution would be interesting for people who are still using WinForms.

Features

The most interesting features of the CTreeView control compared to standard TreeView are:

  • 3 different layouts
  • Multiselection of the nodes
  • Drag and drop nodes
  • Many configurable parameters
  • Possibility of the using in nodes any controls, including standard WinForms controls

All this provides different visual styles of the CTreeView. More detail below.

Sample 1.

Image 2
This is the visual style sample like standard .NET TreeView control. The DrawStyle property is set into "LinearTree". There are user controls in the nodes that contain CheckBox and Label.

Sample 2.

Image 3
This sample demonstrates that standard WinForms controls may be in the nodes. You can't select or drag this nodes because Button, ListBox and other standard classes don't support such things, however you may implement required logic for them using the INodeControl interface. The DrawStyle property is set into "HorizontalDiagram ".

Sample 3.

Image 4

The last sample has "VerticalDiagram" value of the DrawStyle. There are NodeControl objects. They can be selected and dragged depends on SelectionMode and DragAndDropMode of the CTreeView. The SelectionMode has 4 possible values: Multi, MultiSameParent, Single, None. The DragAndDropMode has 3 possible values: ReplaceReorder, Reorder, Nothing. By combining them, you can get different behaviors of user interaction.

Structure

The CTreeView control is modeled on standard TreeView control. The main class CTreeView contains common properties and methods (for example, ExpandAll(), FirstNode, etc.) and collection of CTreeNode objects, that either contains their own collections of nodes. Therefore both CTreeView and CTreeNode classes implement the INodeContainer interface that main function is containing of CTreeNodeCollection object.

Each CTreeNode in the CTreeNodeCollection includes properties and methods (partially overlapping with CTreeView's members) and the Control property to visually represent this node. Control may be any of the standard WinForms controls or special NodeControl derived from UserControl.

The NodeControl class implements specific logic for selection and drag nodes that provides by INodeControl interface (I'm not sure that it's a better way, look at the remarks).

The main aspects of class hierarchy is presented on UML diagram:

Image 5

The VisualStudio class diagrams with all classes, members and fields (also include into project):

Image 6 Image 7

Using the Code

The project's output file is a DLL library. For using of CTreeView control, you must include DLL into your project (use ControlTreeView namespace). For look at CTreeView control, you need just compile and run the code. The "test" project will start.

Example of creating and filling CTreeView with elements of previously created class MyControl : NodeControl:

C#
CTreeView sampleCTreeView = new CTreeView();
Application.OpenForms[0].Controls.Add(sampleCTreeView);
sampleCTreeView.BeginUpdate();
sampleCTreeView.Nodes.Add(new CTreeNode("root node", new MyControl()));
for (int i = 0; i < 5; i++)
{
    sampleCTreeView.Nodes[0].Nodes.Add(new CTreeNode("node " + i, new MyControl()));
}
sampleCTreeView.EndUpdate();

Show every node's name:

C#
sampleCTreeView.Nodes.TraverseNodes((node) =>
{
    MessageBox.Show(node.Name);
});

Show full path of the nodes with name "node 2":

C#
MessageBox.Show(sampleCTreeView.Nodes.Find("node 2", true)[0].FullPath);

Remarks and Further Work

It's my first complicated component, so architecture and code aren't professional-like. It's working in simple applications, but for serious projects it may need some additional work. I'm sure there are a lot of places that may be optimized, for example, positioning node's algorithm, display method, select and drag logic or even class hierarchy itself.

I tried to comment properties and methods like Microsoft TreeView's original comments, but English isn't my native language, so comments also need be corrected for better literacy.

I'm not sure that I will to continue work on this project, however everyone may feel free to do it. The project is available on the GitHub. I would appreciate any help in improving code. Contact me if you have any questions.

History

It's a first revision.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)