操作說明:逐一查看 Windows Forms TreeView 控制項的所有節點

有時候,檢查 Windows Forms TreeView 控制項中的每個節點,以便在節點值上執行一些計算會很有用。 這項作業可以使用遞迴方法(VB.NET 中的遞迴程式)來逐一查看樹狀結構每個集合中的每個節點。

樹狀檢視中的每個 TreeNode 物件都有可用來巡覽樹狀檢視的屬性: FirstNode 、、 LastNodeNextNodePrevNode 、 和 Parent 。 屬性的值 Parent 是目前節點的父節點。 如果有的話,目前節點的子節點會列在其 屬性中 Nodes 。 控制項 TreeView 本身具有 TopNode 屬性,這是整個樹狀檢視的根節點。

遞迴方法

遞迴方法會使用處理樹狀節點的方法,然後為每個子節點呼叫相同的方法。 這會重複,直到處理樹狀結構中的每個節點為止。 此方法的缺點是,如果樹狀結構很大,您可能會遇到堆疊溢位錯誤,而且記憶體不足。

下列範例示範如何列印每個 TreeNode 物件的 Text 屬性:

private void PrintRecursive(TreeNode treeNode)
{
    // Print the node.  
    System.Diagnostics.Debug.WriteLine(treeNode.Text);
    MessageBox.Show(treeNode.Text);

    // Visit each node recursively.  
    foreach (TreeNode tn in treeNode.Nodes)
    {
        PrintRecursive(tn);
    }
}       

// Call the procedure using the TreeView.  
private void CallRecursive(TreeView treeView)
{
    // Print each node recursively.  
    foreach (TreeNode n in treeView.Nodes)
    {
        //recursiveTotalNodes++;
        PrintRecursive(n);
    }
}
Private Sub PrintRecursive(n As TreeNode)
    System.Diagnostics.Debug.WriteLine(n.Text)
    MessageBox.Show(n.Text)
    Dim aNode As TreeNode
    For Each aNode In n.Nodes
        PrintRecursive(aNode)
    Next
End Sub

' Call the procedure using the top nodes of the treeview.  
Private Sub CallRecursive(aTreeView As TreeView)
    Dim n As TreeNode
    For Each n In aTreeView.Nodes
        PrintRecursive(n)
    Next
End Sub
private:
    void PrintRecursive(TreeNode^ treeNode)
    {
        // Print the node.  
        System::Diagnostics::Debug::WriteLine(treeNode->Text);
        MessageBox::Show(treeNode->Text);

        // Print each node recursively.  
        System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(treeNode->Nodes))->GetEnumerator();
        try
        {
            while (myNodes->MoveNext())
            {
                TreeNode^ tn = safe_cast<TreeNode^>(myNodes->Current);
                PrintRecursive(tn);
            }
        }
        finally
        {
            delete(myNodes);
        }
    }

    // Call the procedure using the TreeView.  
    void CallRecursive(TreeView^ treeView)
    {
        // Print each node recursively.  
        TreeNodeCollection^ nodes = treeView->Nodes;
        System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(nodes))->GetEnumerator();
        try
        {
            while (myNodes->MoveNext())
            {
                TreeNode^ n = safe_cast<TreeNode^>(myNodes->Current);
                PrintRecursive(n);
            }
        }
        finally
        {
            delete(myNodes);
        }
    }

非遞迴方法

下列範例是使用集合周遊樹 Queue<T> 狀結構節點的替代反復方法。 此方法不會遵循節點的父子式關聯性,只會確保列印每個節點。 如果您想要處理每個樹狀節點及其子系,請先使用 Stack<T> 集合

private void PrintNonRecursive(TreeNode treeNode)
{
    if (treeNode != null)
    {
        //Using a queue to store and process each node in the TreeView
        Queue<TreeNode> staging = new Queue<TreeNode>();
        staging.Enqueue(treeNode);

        while (staging.Count > 0)
        {
            treeNode = staging.Dequeue();
            
            // Print the node.  
            System.Diagnostics.Debug.WriteLine(treeNode.Text);
            MessageBox.Show(treeNode.Text);

            foreach (TreeNode node in treeNode.Nodes)
            {
                staging.Enqueue(node);
            }
        }
    }
}

// Call the procedure using the TreeView.  
private void CallNonRecursive(TreeView treeView)
{
    // Print each node.
    foreach (TreeNode n in treeView.Nodes)
    {
        PrintNonRecursive(n);
    }
}
Private Sub PrintNonrecursive(n As TreeNode)
    If n IsNot Nothing Then
        Dim staging As Queue(Of TreeNode) = New Queue(Of TreeNode)
        staging.Enqueue(n)
        While staging.Count > 0
            n = staging.Dequeue()

            'Print the node.  
            System.Diagnostics.Debug.WriteLine(n.Text)
            MessageBox.Show(n.Text)

            Dim node As TreeNode
            For Each node In n.Nodes
                staging.Enqueue(node)
            Next
        End While
    End If
End Sub

Private Sub CallNonRecursive(aTreeView As TreeView)
    Dim n As TreeNode
    For Each n In aTreeView.Nodes
        PrintNonrecursive(n)
    Next
End Sub
private:
    void PrintNonRecursive(TreeNode^ treeNode)
    {
        //Using a queue to store and process each node in the TreeView
        Queue^ staging = gcnew Queue();
        staging->Enqueue(treeNode);
        while (staging->Count > 0)
        {
            treeNode = safe_cast<TreeNode^>(staging->Dequeue());

            // Print the node.  
            System::Diagnostics::Debug::WriteLine(treeNode->Text);
            MessageBox::Show(treeNode->Text);

            System::Collections::IEnumerator^ children = (safe_cast<System::Collections::IEnumerable^>(treeNode->Nodes))->GetEnumerator();
            try 
            {
                while (children->MoveNext())
                {
                    staging->Enqueue(children->Current);
                }
            }
            finally
            {
                delete(children);
            }                
        }

        // Print the node.  
        System::Diagnostics::Debug::WriteLine(treeNode->Text);
        MessageBox::Show(treeNode->Text);

        // Print each node recursively.  
        System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(treeNode->Nodes))->GetEnumerator();
        try
        {
            while (myNodes->MoveNext())
            {
                TreeNode^ tn = safe_cast<TreeNode^>(myNodes->Current);
                PrintRecursive(tn);
            }
        }
        finally
        {
            delete(myNodes);
        }
    }

    // Call the procedure using the TreeView.  
    void CallNonRecursive(TreeView^ treeView)
    {
        // Print each node recursively.  
        TreeNodeCollection^ nodes = treeView->Nodes;
        System::Collections::IEnumerator^ myNodes = (safe_cast<System::Collections::IEnumerable^>(nodes))->GetEnumerator();
        try
        {
            while (myNodes->MoveNext())
            {
                TreeNode^ n = safe_cast<TreeNode^>(myNodes->Current);
                PrintNonRecursive(n);
            }
        }
        finally
        {
            delete(myNodes);
        }
    }

另請參閱