방법: Windows Forms TreeView 컨트롤의 모든 노드 반복

노드 값에 대해 몇 가지 계산을 수행하기 위해 Windows Forms TreeView 컨트롤에서 모든 노드를 검사하는 데 유용합니다. 트리의 각 컬렉션의 각 노드를 반복하는 재귀 메서드(VB.NET의 재귀 메서드)를 사용하여 이 작업을 수행할 수 있습니다.

트리 뷰의 각 TreeNode 개체에는 트리 뷰를 탐색하는 데 사용할 수 있는 FirstNode, LastNode, NextNode, PrevNodeParent 속성이 있습니다. 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);
        }
    }

참고 항목