How can I get a list of all tree nodes (in all levels) in a TreeView control?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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;
}
Method 2
Assuming you have a tree with one root node the following code will always loop the tree nodes down to the deepest, then go one level back and so on. It will print the text of each node.
(Untested from the top of my head)
TreeNode oMainNode = oYourTreeView.Nodes[0];
PrintNodesRecursive(oMainNode);
public void PrintNodesRecursive(TreeNode oParentNode)
{
Console.WriteLine(oParentNode.Text);
// Start recursion on all subnodes.
foreach(TreeNode oSubNode in oParentNode.Nodes)
{
PrintNodesRecursive(oSubNode);
}
}
Method 3
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;
}
Method 4
Update to Krumelur’s answer (replace 2 first lines of his/her solution with this):
foreach ( var node in oYourTreeView.Nodes )
{
PrintNodesRecursive( node );
}
Method 5
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
Method 6
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.
Method 7
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);
Method 8
If you need some processing across all nodes of a treeview, you could use a stack rather than recursive methods:
Stack<TreeNode> nodeStack = new Stack<TreeNode>(treeview1.Nodes.Cast<TreeNode>());
while(nodeStack.Count > 0)
{
TreeNode node = nodeStack.Pop();
// Do your processing on the node here...
// Add all children to the stack
if(node.Nodes.Count > 0)
foreach(TreeNode child in node.Nodes)
nodeStack.Push(child);
}
Method 9
This code help you to iterate though all TreeView list with identifying current depth level. Code can be used to save TreeView items to XML file and other purposes.
int _level = 0;
TreeNode _currentNode = treeView1.Nodes[0];
do
{
MessageBox.Show(_currentNode.Text + " " + _level);
if (_currentNode.Nodes.Count > 0)
{
_currentNode = _currentNode.Nodes[0];
_level++;
}
else
{
if (_currentNode.NextNode != null)
_currentNode = _currentNode.NextNode;
else
{
_currentNode = _currentNode.Parent.NextNode;
_level--;
}
}
}
while (_level > 0);
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0