How can I get a list of all tree nodes (in all levels) in a TreeView
control?
You can use two recursive extension methods. You can either call myTreeView.GetAllNodes()
or myTreeNode.GetAllNodes()
:
public static List<TreeNode> GetAllNodes(this TreeView _self)
{
List<TreeNode> result = new List<TreeNode>();
foreach (TreeNode child in _self.Nodes)
{
result.AddRange(child.GetAllNodes());
}
return result;
}
public static List<TreeNode> GetAllNodes(this TreeNode _self)
{
List<TreeNode> result = new List<TreeNode>();
result.Add(_self);
foreach (TreeNode child in _self.Nodes)
{
result.AddRange(child.GetAllNodes());
}
return result;
}
If you don't need the node Key to be unique, just set all of the node keys to an empty string (""
), then you can do a Treeview1.Nodes.Find("", true);
to return all nodes within a TreeView.
Update to Krumelur's answer (replace 2 first lines of his/her solution with this):
foreach ( var node in oYourTreeView.Nodes )
{
PrintNodesRecursive( node );
}
Because TreeView has many levels, do recursive function:
public void AddNodeAndChildNodesToList(TreeNode node)
{
listBox1.Items.Add(node.Text); // Adding current nodename to ListBox
foreach (TreeNode actualNode in node.Nodes)
{
AddNodeAndChildNodesToList(actualNode); // recursive call
}
}
Than call this function for all first level Nodes in TreeView:
foreach (TreeNode actualNode in treeView1.Nodes) // Begin with Nodes from TreeView
{
AddNodeAndChildNodesToList(actualNode);
}
Code is from site C# TreeView
I think my solution is more elegant, it uses generics (because TreeView can store each kind of objects derived from TreeNode) and has a single function recursively called. It should be straightforward also convert this as extension.
List<T> EnumerateAllTreeNodes<T>(TreeView tree, T parentNode = null) where T : TreeNode
{
if (parentNode != null && parentNode.Nodes.Count == 0)
return new List<T>() { };
TreeNodeCollection nodes = parentNode != null ? parentNode.Nodes : tree.Nodes;
List<T> childList = nodes.Cast<T>().ToList();
List<T> result = new List<T>(1024); //Preallocate space for children
result.AddRange(childList); //Level first
//Recursion on each child node
childList.ForEach(n => result.AddRange(EnumerateAllTreeNodes(tree,n)));
return result;
}
The usage is straightforward, just call:
List<MyNodeType> allnodes = EnumerateAllTreeNodes<MyNodeType>(tree);
Lazy LINQ approach, just in case you're looking for something like this:
private void EnumerateAllNodes()
{
TreeView myTree = ...;
var allNodes = myTree.Nodes
.Cast<TreeNode>()
.SelectMany(GetNodeBranch);
foreach (var treeNode in allNodes)
{
// Do something
}
}
private IEnumerable<TreeNode> GetNodeBranch(TreeNode node)
{
yield return node;
foreach (TreeNode child in node.Nodes)
foreach (var childChild in GetNodeBranch(child))
yield return childChild;
}