Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在.NET中获取树视图中所有子节点的列表_.net_Vb.net_Treeview_Tree Nodes - Fatal编程技术网

如何在.NET中获取树视图中所有子节点的列表

如何在.NET中获取树视图中所有子节点的列表,.net,vb.net,treeview,tree-nodes,.net,Vb.net,Treeview,Tree Nodes,我在WinForms.NET应用程序中有一个TreeView控件,该控件具有多个级别的childnodes,其中childnodes具有更多的childnodes,并且没有定义深度。当用户选择任何父节点(不一定在根级别)时,如何获得该父节点上所有节点的列表 例如,我从以下内容开始: Dim nodes As List(Of String) For Each childNodeLevel1 As TreeNode In parentNode.Nodes For Each childNod

我在WinForms.NET应用程序中有一个TreeView控件,该控件具有多个级别的childnodes,其中childnodes具有更多的childnodes,并且没有定义深度。当用户选择任何父节点(不一定在根级别)时,如何获得该父节点上所有节点的列表

例如,我从以下内容开始:

Dim nodes As List(Of String)

For Each childNodeLevel1 As TreeNode In parentNode.Nodes
    For Each childNodeLevel2 As TreeNode In childNodeLevel1.Nodes
        For Each childNodeLevel3 As TreeNode In childNodeLevel2.Nodes
            nodes.Add(childNodeLevel3.Text)
        Next
    Next
Next

问题是这个循环的深度是被定义的,我只把节点埋在三层。如果用户下次选择父节点时,有七个级别怎么办?

您需要一个递归函数来完成此操作[或一个等效的循环,但递归版本更简单]-伪代码:

function outputNodes(Node root)
    writeln(root.Text)
    foreach(Node n in root.ChildNodes)
        outputNodes(n)
    end
end
使用递归

Function GetChildren(parentNode as TreeNode) as List(Of String)
  Dim nodes as List(Of String) = New List(Of String)
  GetAllChildren(parentNode, nodes)
  return nodes
End Function

Sub GetAllChildren(parentNode as TreeNode, nodes as List(Of String))
  For Each childNode as TreeNode in parentNode.Nodes
    nodes.Add(childNode.Text)
    GetAllChildren(childNode, nodes)
  Next
End Sub

下面是我从核心库中执行此任务的代码片段。
它允许您在不使用递归的情况下,以深度优先或呼吸优先的方式列出节点,这会增加JIT引擎中构造stackframes的开销。非常快

要使用它,只需执行以下操作:

List< TreeNode > nodes = TreeViewUtils.FlattenDepth(tree);
Listnodes=TreeViewUtils.flatteDepth(树);
很抱歉,您有一个VB.Net标记;我不能举个例子,但我相信你会解决的

公共类TreeViewTils
{
/// 
///此静态实用性方法使用
///基于队列的呼吸优先搜索,而不是开销
///递归方法调用的类型。
/// 
/// 
/// 
公共静态列表(TreeView树){
列表节点=新列表();
队列=新队列();
//
//将所有顶部节点放入队列中。
//
foreach(tree.Nodes中的树节点顶部){
排队。排队(顶部);
}
而(queue.Count>0){
TreeNode节点=queue.Dequeue();
如果(节点!=null){
//
//将节点添加到节点列表中。
//
nodes.Add(node);
如果(node.Nodes!=null&&node.Nodes.Count>0){
//
//使子节点排队。
//
foreach(node.Nodes中的树节点子节点){
排队。排队(子级);
}
}
}
}
返回节点;
}
/// 
///此静态实用性方法使用
///基于堆栈的深度优先搜索,而不是开销
///递归方法调用的类型。
/// 
/// 
/// 
公共静态列表深度(TreeView树){
列表节点=新列表();
堆栈=新堆栈();
//
//将所有顶部节点放入队列中。
//
foreach(tree.Nodes中的树节点顶部){
栈。推(顶);
}
而(stack.Count>0){
TreeNode节点=stack.Pop();
如果(节点!=null){
//
//将节点添加到节点列表中。
//
nodes.Add(node);
如果(node.Nodes!=null&&node.Nodes.Count>0){
//
//使子节点排队。
//
foreach(node.Nodes中的树节点子节点){
栈.推(子);
}
}
}
}
返回节点;
}
}

我已将代码转换为
VB.Net
,结果如下:

Public Function FlattenBreadth(ByVal tree As TreeView) As List(Of TreeNode)
    Dim nodes As New List(Of TreeNode)
    Dim queue As New Queue(Of TreeNode)
    Dim top As TreeNode
    Dim nod As TreeNode
    For Each top In tree.Nodes
        queue.Enqueue(top)
    Next
    While (queue.Count > 0)
        top = queue.Dequeue
        nodes.Add(top)
        For Each nod In top.Nodes
            queue.Enqueue(nod)
        Next
    End While
    FlattenBreadth = nodes
End Function

我有一个扩展方法用于此:

public static IEnumerable<TreeNode> DescendantNodes( this TreeNode input ) {
    foreach ( TreeNode node in input.Nodes ) {
        yield return node;
        foreach ( var subnode in node.DescendantNodes() )
            yield return subnode;
        }
}
公共静态IEnumerable子代节点(此树节点输入){
foreach(input.Nodes中的TreeNode节点){
收益回报节点;
foreach(node.degenantNodes()中的var子节点)
产生返回子节点;
}
}
它是C#,但可以从VB中引用或转换为它

nodParent As TreeNode
'nodParent = your parent Node
tvwOpt.Nodes.Find(nodParent.Name, True)

这就是阿德里安的方法,太棒了。工作速度相当快,比递归方法工作得更好。我已经翻译成VB了。我从中学到了很多。希望有人还需要它

简单地说:

Dim FlattenedNodes As List(Of TreeNode) = clTreeUtil.FlattenDepth(Me.TreeView1) 
这是密码,干杯

Public Class clTreeUtil
''' <summary>
''' This static utiltiy method flattens all the nodes in a tree view using
''' a queue based breath first search rather than the overhead
''' of recursive method calls.
''' </summary>
''' <param name="tree"></param>
''' <returns></returns>
Public Shared Function FlattenBreath(Tree As TreeView) As List(Of TreeNode)
    Dim nodes As List(Of TreeNode) = New List(Of TreeNode)
    Dim queue As Queue(Of TreeNode) = New Queue(Of TreeNode)

    ''
    '' Bang all the top nodes into the queue.
    ''
    For Each top As TreeNode In Tree.Nodes
        queue.Enqueue(top)
    Next

    While (queue.Count > 0)
        Dim node As TreeNode = queue.Dequeue()
        If node IsNot Nothing Then
            ''
            '' Add the node to the list of nodes.
            ''
            nodes.Add(node)

            If node.Nodes IsNot Nothing And node.Nodes.Count > 0 Then
                ''
                '' Enqueue the child nodes.
                ''
                For Each child As TreeNode In node.Nodes
                    queue.Enqueue(child)
                Next
            End If
        End If
    End While

    Return nodes
End Function

''' <summary>
''' This static utiltiy method flattens all the nodes in a tree view using
''' a stack based depth first search rather than the overhead
''' of recursive method calls.
''' </summary>
''' <param name="tree"></param>
''' <returns></returns>
Public Shared Function FlattenDepth(tree As TreeView) As List(Of TreeNode)
    Dim nodes As List(Of TreeNode) = New List(Of TreeNode)

    Dim stack As Stack(Of TreeNode) = New Stack(Of TreeNode)

    ''
    '' Bang all the top nodes into the queue.
    ''
    For Each top As TreeNode In tree.Nodes
        stack.Push(top)
    Next

    While (stack.Count > 0)
        Dim node As TreeNode = stack.Pop()

        If node IsNot Nothing Then

            ''
            '' Add the node to the list of nodes.
            ''
            nodes.Add(node)

            If node.Nodes IsNot Nothing And node.Nodes.Count > 0 Then
                ''
                '' Enqueue the child nodes.
                ''
                For Each child As TreeNode In node.Nodes
                    stack.Push(child)
                Next
            End If
        End If

    End While

    Return nodes
End Function

End Class
公共类clTreeUtil
''' 
''此静态实用性方法使用
''基于队列的呼吸优先搜索,而不是开销
递归方法调用的“”。
''' 
''' 
''' 
公共共享功能(树为TreeView)作为列表(树节点)
Dim节点作为列表(树节点)=新列表(树节点)
Dim队列作为队列(树节点)=新队列(树节点)
''
“”将所有顶部节点放入队列中。
''
在Tree.Nodes中为每个top As TreeNode
队列。排队(顶部)
下一个
而(queue.Count>0)
作为TreeNode=queue.Dequeue()的Dim节点
如果node不是空的,那么
''
“”将节点添加到节点列表中。
''
添加(节点)
如果node.Nodes不是Nothing且node.Nodes.Count>0,则
''
“”使子节点排队。
''
在node.Nodes中为每个子节点指定树节点
queue.Enqueue(子级)
下一个
如果结束
如果结束
结束时
返回节点
端函数
''' 
''此静态实用性方法使用
''基于堆栈的深度优先搜索,而不是开销
递归方法调用的“”。
''' 
''' 
''' 
公共共享函数(树为TreeView)作为列表(树节点)
Dim节点作为列表(树节点)=新列表(树节点)
将堆栈作为堆栈(TreeNode的)=新堆栈(TreeNode的)
''
“”将所有顶部节点放入队列中。
''
在tree.Nodes中为每个top As TreeNode
堆栈推送(顶部)
下一个
而(stack.Count>0)
作为TreeNode=stack.Pop()的Dim节点
如果node不是空的,那么
''
“”将节点添加到节点列表中。
''
添加(节点)
Public Shared Function GetChildren(objTree As TreeView) As List(Of TreeNode)
    Dim nodes As List(Of TreeNode) = New List(Of TreeNode)
    For Each parentNode As TreeNode In objTree.Nodes
        nodes.Add(parentNode)
        GetAllChildren(parentNode, nodes)
    Next

    Return nodes
End Function

Public Shared Sub GetAllChildren(parentNode As TreeNode, nodes As List(Of TreeNode))
    For Each childNode As TreeNode In parentNode.Nodes
        nodes.Add(childNode)
        GetAllChildren(childNode, nodes)
    Next
End Sub
textbox1.Text = treeview1.nodes(0).Text.ToString()
public static IEnumerable<TreeNode> DescendantNodes2(this TreeView input)
{
    foreach (TreeNode node in input.Nodes)
    {
        yield return node;
        foreach (var subnode in node.DescendantNodes())
            yield return subnode;
    }
}
private static IEnumerable<TreeNode> DescendantNodes(this TreeNode input)
{
    foreach (TreeNode node in input.ChildNodes)
    {
        yield return node;
        foreach (var subnode in node.DescendantNodes())
            yield return subnode;
    }
}