Nasıl yapılır: Bir Windows Forms TreeView Denetiminin Tüm Düğümlerinde Yineleme

Bazen düğüm değerleri üzerinde hesaplama yapmak için Windows Forms TreeView denetiminde her düğümü incelemek yararlı olabilir. Bu işlem, ağacın her koleksiyonunda her düğümde tekrarlayan bir VB.NET yöntemi (VB.NET yordam) kullanılarak yapılabilir.

Ağaç TreeNode görünümündeki her nesne, ağaç görünümünde gezinmek için kullanabileceğiniz özelliklere sahiptir: FirstNode , , , ve LastNode NextNode PrevNode Parent . özelliğinin Parent değeri, geçerli düğümün üst düğümü olur. Varsa, geçerli düğümün alt düğümleri özelliğinde Nodes listelenir. Denetimin TreeView TopNode kendisi, tüm ağaç görünümünün kök düğümü olan özelliğine sahiptir.

Recursive yaklaşımı

Recursive yaklaşımı, bir ağaç düğümünü işlayan bir yöntem kullanır ve ardından her alt düğüm için aynı yöntemi çağıran bir yöntem kullanır. Bu işlem, ağaçtaki her düğüm işlenene kadar yineler. Bu yaklaşımın dezavantajı, ağacın büyük olduğu durumda yığın taşması hatasıyla ve yetersiz bellekle karşılayabilirsiniz.

Aşağıdaki örnekte her bir nesnenin TreeNode özelliğinin nasıl yazdırılacakları Text gösterir:

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);
        }
    }

Recursive olmayan yaklaşım

Aşağıdaki örnek, bir koleksiyon kullanarak ağacın düğümlerini çapraz geçiş yapmak için alternatif bir iterative Queue<T> yaklaşımdır. Bu yaklaşım, bir düğümün üst-alt ilişkisini izlemez; yalnızca her düğümün yazdırılmış olması garanti eder. Her ağaç düğümünü ve alt düğümlerini işlemek için önce koleksiyonunu Stack<T> kullanın

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);
        }
    }

Ayrıca bkz.