I am selecting all controls I have in a form
if controls are Treeviews
, I'll iterate all nodes they have
I need something like: (And it is my code)
foreach (Control c in PanelSM.Controls)
{
if (c is TreeView)
{
TreeNodeCollection myNodes = c.Nodes;//<<<<< Here is a mistake
foreach (TreeNode n in myNodes)
{
String text = rm.GetString(n.Name);
//And more things
//...
//...
//...
}
}
//...
}
Any idea?
Thank You
You need to use recursion. A method like this should suffice
IEnumerable<TreeNode> Collect(TreeNodeCollection nodes)
{
foreach(TreeNode node in nodes)
{
yield return node;
foreach (var child in Collect(node.Nodes))
yield return child;
}
}
Then in your method you can just do
foreach (var node in Collect(tree.Nodes))
{
// you will see every child node here
}
It's pretty easy:
void TraverseTree(TreeNodeCollection nodes)
{
foreach (var child in nodes)
{
DoSomethingWithNode(child);
TraverseTree(child.Nodes);
}
}
And call it with:
TraverseTree(MyTreeView.Nodes);
Your mistake is that c
is actually a variable of type Control
, which does not have a Nodes member. You will need it to cast it as a TreeView
type.
You can do either of these two approaches:
if (c is TreeView)
{
TreeNodeCollection myNodes = ((TreeView) c).Nodes; // <<--- Note the cast
...
}
or
TreeView tv = c as TreeView;
if (tv != null)
{
TreeNodeCollection myNodes = tv.Nodes;
...
}
I prefer simplicity, and here is my simple solution:
protected void TraverseNodes(TreeNodeCollection nodes, string action, int maxDepth = 2)
{
foreach (TreeNode node in nodes)
{
if (node.ChildNodes.Count > 0 && node.Depth < maxDepth)
TraverseNodes(node.ChildNodes, action, maxDepth);
//do something!!!
var x = node.Text;
node.Checked = !node.Checked;
}
}
I decided to include a "maximum depth" as a bonus, so enjoy.
Call it as follows:
TraverseNodes(this.Activities.Nodes, "");
Unlike some of the examples posted here, I actually tested this (ouch! I can hear them say).
try this
foreach (TreeNode t in tvMenu.Nodes)
{
for (int iParent = 0; iParent < t.ChildNodes.Count; iParent++)
{
for (int iChild = 0; iChild < t.ChildNodes[iParent].ChildNodes.Count; iChild++)
{
if (t.ChildNodes[iParent].ChildNodes[iChild].Text == "")
{
}
}
}
}
Building on top of Darren's great answer, you can combine recursion and class extension .
Declare somewhere in your namespace :
public static class MyExtensions
{
public static IEnumerable<TreeNode> All( this TreeNodeCollection nodes )
{
foreach( TreeNode n in nodes )
{
yield return n;
foreach( TreeNode child in n.Nodes.All( ) )
yield return child;
}
}
}
Note the "this" before the first argument of the method.
Then you can use this new method in all treeviews as:
foreach( TreeNode n in myTreeview.Nodes.All() ) ...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.