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.
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.
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.
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:
The VisualStudio class diagrams with all classes, members and fields (also include into project):
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
:
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:
sampleCTreeView.Nodes.TraverseNodes((node) =>
{
MessageBox.Show(node.Name);
});
Show full path of the nodes with name "node 2":
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.