Vorgehensweise: Durchlaufen aller Knoten eines TreeView-Steuerelements in Windows Forms

Manchmal ist es sinnvoll, alle Knoten in einem TreeView-Steuerelement in Windows Forms zu untersuchen, um Berechnungen mit den Knotenwerten durchzuführen. Dieser Vorgang kann über eine rekursive Methode (rekursive Prozedur in VB.NET) ausgeführt werden, die alle Knoten der einzelnen Auflistungen der Struktur durchläuft.

Jedes TreeNode-Objekt in einer Strukturansicht verfügt über Eigenschaften, mit denen Sie durch die Strukturansicht navigieren können: FirstNode, LastNode, NextNode, PrevNode und Parent. Der Wert der Parent-Eigenschaft ist der übergeordnete Knoten des aktuellen Knotens. Die untergeordneten Knoten des aktuellen Knotens werden, falls vorhanden, in der Nodes-Eigenschaft aufgelistet. Das TreeView-Steuerelement selbst umfasst die TopNode-Eigenschaft, die der Stammknoten der gesamten Strukturansicht ist.

Rekursive Vorgehensweise

Bei der rekursiven Vorgehensweise wird eine Methode verwendet, die einen Strukturknoten verarbeitet. Die gleiche Methode wird dann für jeden untergeordneten Knoten aufgerufen. Dies wird solange wiederholt, bis jeder Knoten in der Struktur verarbeitet wurde. Der Nachteil dieser Vorgehensweise besteht darin, dass bei einer umfangreichen Struktur u. U. ein Stapelüberlauffehler auftreten kann und der verfügbare Arbeitsspeicher nicht ausreicht.

Im folgenden Beispiel wird veranschaulicht, wie die Text-Eigenschaft jedes TreeNode-Objekts gelesen wird:

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

Nicht rekursive Vorgehensweise

Im folgenden Beispiel handelt es sich um eine alternative iterative Vorgehensweise zum Durchlaufen der Knoten der Struktur unter Verwendung einer Queue<T>-Auflistung. Diese Vorgehensweise folgt nicht der hierarchischen Beziehung eines Knotens, um zu gewährleisten, dass jeder Knoten ausgegeben wird. Wenn Sie jeden Strukturknoten und dessen untergeordneten Elemente verarbeiten möchten, verwenden Sie zuerst die Stack<T>-Auflistung.

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

Weitere Informationen