First, instead of reinventing the wheel, I would take the helper function from my answer to How to flatten tree via LINQ? which is very useful for any tree like structures:
public static class TreeUtils
{
public static IEnumerable<T> Expand<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> elementSelector)
{
var stack = new Stack<IEnumerator<T>>();
var e = source.GetEnumerator();
try
{
while (true)
{
while (e.MoveNext())
{
var item = e.Current;
yield return item;
var elements = elementSelector(item);
if (elements == null) continue;
stack.Push(e);
e = elements.GetEnumerator();
}
if (stack.Count == 0) break;
e.Dispose();
e = stack.Pop();
}
}
finally
{
e.Dispose();
while (stack.Count != 0) stack.Pop().Dispose();
}
}
}
Then I would create a couple TreeView
specific helpers:
public static class TreeViewUtils
{
public static IEnumerable<TreeNode> AsEnumerable(this TreeNodeCollection source)
{
return source.Cast<TreeNode>();
}
public static IEnumerable<TreeNode> All(this TreeNodeCollection source)
{
return source.AsEnumerable().Expand(node => node.Nodes.Count > 0 ? node.Nodes.AsEnumerable() : null);
}
public static TreeNode Find(this TreeNodeCollection source, int index)
{
return source.All().Skip(index).FirstOrDefault();
}
}
Now to get the i-th
node of the tree view you can simply use
var node = treeview1.Nodes.Find(i);
Additionally you can get the i-th
child node of any node like this
var childNode = node.Nodes.Find(i);
To conclude, I've could easily provided a recursive function that just solves the specific question with less code, but this little utility functions give you much more - foreach
support, all nodes of a subtree DFT traversal, LINQ queries (like searching by Tag
or some other criteria) etc.
UPDATE
Strange requirement nowadays, but here is the "raw" C# function (no LINQ, no extension methods, no iterator methods) doing just what you need
public static class TreeViewUtils
{
public static TreeNode FindNode(TreeNodeCollection nodes, int index)
{
int offset = -1;
return FindNode(nodes, ref offset, index);
}
private static TreeNode FindNode(TreeNodeCollection nodes, ref int offset, int index)
{
for (int i = 0; i < nodes.Count; i++)
{
var node = nodes[i];
if (++offset == index || (node = FindNode(node.Nodes, ref offset, index)) != null)
return node;
}
return null;
}
}
and the respective usage
var node = TreeViewUtils.FindNode(treeview1.Nodes, i);
or
var childNode = TreeViewUtils.FindNode(node.Nodes, i);