Freigeben über


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

Es ist manchmal nützlich, jeden Knoten in einem Windows Forms-TreeView-Steuerelement zu untersuchen, um einige Berechnungen für die Knotenwerte durchzuführen. Dieser Vorgang kann mithilfe einer rekursiven Methode (rekursive Prozedur in VB.NET) durchgeführt werden, die jeden Knoten in jeder Auflistung des Baums durchläuft.

Jedes TreeNode -Objekt in einer Strukturansicht verfügt über Eigenschaften, mit denen Sie in der Strukturansicht navigieren können: FirstNode, LastNode, NextNode, PrevNodeund Parent. Der Wert der Parent-Eigenschaft ist der übergeordnete Knoten des aktuellen Knotens. Die untergeordneten Knoten des aktuellen Knotens, falls vorhanden, werden in der Nodes-Eigenschaft aufgeführt. Das TreeView-Steuerelement selbst verfügt über die TopNode-Eigenschaft, bei der es sich um den Stammknoten der gesamten Strukturansicht handelt.

Rekursiver Ansatz

Der rekursive Ansatz verwendet eine Methode, die einen Baumknoten verarbeitet und dann die gleiche Methode für jeden seiner Kindknoten aufruft. Dies wird wiederholt, bis jeder Knoten im Baum verarbeitet wird. Der Nachteil dieses Ansatzes besteht darin, dass, wenn der Baum groß ist, möglicherweise ein Stapelüberlauffehler auftritt und der Arbeitsspeicher knapp wird.

Das folgende Beispiel zeigt, wie die Text-Eigenschaft jedes Objekts TreeNode gedruckt 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 rekursiver Ansatz

Das folgende Beispiel ist eine alternative iterative Methode zum Durchlaufen der Knoten des Baums mithilfe einer Queue<T>-Auflistung. Dieser Ansatz folgt nicht der Eltern-Kind-Beziehung von Knoten, sondern stellt nur sicher, dass jeder Knoten gedruckt wird. Wenn Sie jeden Baumknoten und seine Kindknoten verarbeiten möchten, verwenden Sie zunächst die Stack<T>-Datenstruktur.

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

Siehe auch