Simply adding some nodes hierarchically to a TreeView control. category 'experiment', language C#, created 12-Aug-2009, version V1.2 (04-Dec-2009), by Luc Pattyn |
License: The author hereby grants you a worldwide, non-exclusive license to use and redistribute the files and the source code in the article in any way you see fit, provided you keep the copyright notice in place; when code modifications are applied, the notice must reflect that. The author retains copyright to the article, you may not republish or otherwise make available the article, in whole or in part, without the prior written consent of the author. Disclaimer: This work is provided |
I hadn't used the standard TreeView
Control yet, so I decided to perform a little test with it.
I don't use tree views that often, and when I do I tend to need lots of extra functionality and
roll my own Control.
The environment used is the Microsoft .NET Framework (version 2.0 or above) and the C# programming language. The nodes to be displayed are taken from a simple text file:
root
root/folder1
root/folder2
root/folder2/subfolder1
root/folder2/subfolder2/subfolder3
root/folder3/subfolder4
root/folder4
This is the bulk of the code; the heart of the matter is the AddPath()
method
which contains a foreach loop to process the individual parts of each path:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
namespace TreeView1 {
public class Form1 : Form {
public Form1() {
InitializeComponent();
Size=new Size(SystemInformation.PrimaryMonitorSize.Width-150,
SystemInformation.PrimaryMonitorSize.Height-50);
}
private void log(string s) {
lb.Items.Add(s);
lb.TopIndex=lb.Items.Count-1;
}
private void log(Exception exc) {
foreach(string s in exc.ToString().Split('\n','\r')) if (s.Length!=0) log(s);
}
private void Form1_Shown(object sender, EventArgs e) {
try {
string[] paths=File.ReadAllLines("paths.txt");
int count=0;
foreach (string path in paths) AddPath(path, ref count);
tv.ExpandAll();
log("========================== Done (created "+count+" nodes)");
} catch (Exception exc) { log(exc); }
}
private void AddPath(string path, ref int count) {
log("========================== creating "+path);
TreeNodeCollection nodes=tv.Nodes;
foreach (string nodeName in path.Split('/')) {
log("nodeName="+nodeName);
TreeNode found;
if (nodes.ContainsKey(nodeName)) {
found=nodes.Find(nodeName, false)[0];
} else {
count++;
found=nodes.Add(nodeName);
found.Name=nodeName; // find() looks for Name, not Text
log("added node "+nodeName);
}
nodes=found.Nodes;
}
}
}
}
And here is the designer-generated code which has to be added to the above to set up the GUI; a ListBox is used for logging, as I often do:
private void InitializeComponent() {
this.tv = new System.Windows.Forms.TreeView();
this.lb = new System.Windows.Forms.ListBox();
this.SuspendLayout();
//
// tv
//
this.tv.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left)));
this.tv.Location = new System.Drawing.Point(34, 19);
this.tv.Name = "tv";
this.tv.Size = new System.Drawing.Size(369, 341);
this.tv.TabIndex = 0;
//
// lb
//
this.lb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.lb.FormattingEnabled = true;
this.lb.Location = new System.Drawing.Point(441, 18);
this.lb.Name = "lb";
this.lb.Size = new System.Drawing.Size(409, 342);
this.lb.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(863, 384);
this.Controls.Add(this.lb);
this.Controls.Add(this.tv);
this.Name = "Form1";
this.Text = "TreeView Experiment";
this.Shown += new System.EventHandler(this.Form1_Shown);
this.ResumeLayout(false);
}
private System.Windows.Forms.TreeView tv;
private System.Windows.Forms.ListBox lb;
A TreeView differs from other list oriented Controls such as ListBox
and ComboBox
in that it holds
items ("nodes") in a hierarchical way, which implies each node needs the capability to hold a collection of child nodes.
The net result is a TreeView only accepts TreeNode
instances, which can be created explicitly or implicitly.
When the nodes in a TreeView should hold more information than just a display string, there basically are two ways to
store user-defined nodes (e.g. instances of MyTreeNode
):
TreeNode
instances, and store a reference to your own MyTreeNode
in the TreeNode.Tag
property, which is available for any use one sees fit; this works whatever the definition of MyTreeNode
is but
requires you to write myTreeView.Nodes[i].Tag
to get at your extra information;MyTreeNode
inherits from TreeNode
;
the advantage is the Tag
property isn't used at all, however this is feasible only when no other inheritance
is required as C# (or VB.NET) don't support multiple inheritance.In both cases the TreeNode needs its Text
property set to the display text;
as well as its Name
property if you want the Find()
method to work.
Overriding the ToString()
method does not change that.
Nothing special to report, it works as expected.
Perceler |
Copyright © 2012, Luc Pattyn |
Last Modified 20-Dec-2024 |