TreeView-Knoten sortieren

Veröffentlicht: 10. Jan 2005

Von Mathias Schiffer

Das ListView-Steuerelement von Windows Forms bietet wie selbstverständlich eine Sort-Methode an. Nichts dergleichen hingegen findet sich beim TreeView-Steuerelement. Wir schaffen Abhilfe.

Das .NET Framework bietet mit der CompareTo-Funktion einen komfortablen Weg an, zwei Elemente miteinander zu vergleichen. Dank ihrer Hilfe ist es nur noch ein Schritt bis zur Sortierung von Elementen einer Menge, wie schon im MSDN Quickie „Arraysortierungen mit Visual Basic .NET“ gezeigt.

In diesem MSDN Quickie werden wir diese praktische Funktion verwenden, um Texteinträge eines Treeview-Knotens zu sortieren. Die grundlegende Idee des einfachen Algorithmus ist dabei, zwei Elemente der Knoteneinträge zu vergleichen und bei unpassender Sortierung gegeneinander auszutauschen.

TreeView-Knotensortierung

Die Methode SortNodes erledigt diese Aufgabe für Sie: Sie übergeben einfach ein Objekt vom Typ NodesCollection, das die Elemente eines TreeView-Knotens enthält (z.B. die Nodes-Eigenschaft des TreeView-Steuerelements selbst für die oberste Knotenebene). Zusätzlich können Sie noch angeben, ob dessen Einträge alphabetisch aufwärts oder abwärts sortiert werden sollen:

  Public Sub SortNodes(ByVal NodesCollection As System.Windows.Forms.TreeNodeCollection, _
                       Optional ByVal Ascending As Boolean = True)
    Dim node1, node2 As System.Windows.Forms.TreeNode
    Dim iTn1, iTn2 As Integer
    Dim k As Integer
    Dim iCompareResult As Integer
  
    ' Alle Knoten durchwandern
    For i As Integer = 0 To NodesCollection.Count
  
      k = NodesCollection.Count
  
      Do While k > i
  
        k -= 1
  
        ' Je zwei Nodes ermitteln und Texte vergleichen
        node1 = NodesCollection(i)
        node2 = NodesCollection(k)
        Console.WriteLine(node1.Text & ", " & node2.Text)
        iCompareResult = node1.Text.CompareTo(node2.Text)
  
        ' Falls die Sortierung nicht dem übergebenen Sortierkriterium entspricht:
        If (Ascending = True And iCompareResult > 0) _
           OrElse _
           (Ascending = False And iCompareResult < 0) Then
  
          ' Nodes austauschen
          With NodesCollection
            .Remove(node1)
            .Remove(node2)
            .Insert(i, node2)
            .Insert(k, node1)
          End With
  
        End If
  
      Loop
  
    Next
  
  End Sub

 

Unterknotensortierung per Rekursion

Eine kleine Erweiterung der Prozedur ermöglicht es, nicht nur eine Nodes-Ebene zu sortieren: Durch den Einbau eines simpel gehaltenen Rekursionsschritts kann in der folgenden Variante der zusätzliche Parameter SortChildNodes zu True gesetzt werden, um auch alle Node-Ebenen unterhalb der übergebenen Ebene identisch sortieren zu können:

  Public Sub SortNodes(ByVal NodesCollection As System.Windows.Forms.TreeNodeCollection, _
                       Optional ByVal Ascending As Boolean = True, _
                       Optional ByVal SortChildNodes As Boolean = False)
    Dim node1, node2 As System.Windows.Forms.TreeNode
    Dim iTn1, iTn2 As Integer
    Dim k As Integer
    Dim iCompareResult As Integer
  
    ' SortChildNodes: Ggf. Rekursion einleiten
    If SortChildNodes Then
      For i As Integer = 0 To NodesCollection.Count - 1
        Call SortNodes(NodesCollection(i).Nodes, Ascending, SortChildNodes)
      Next i
    End If
  
    ' Alle Knoten durchwandern
    For i As Integer = 0 To NodesCollection.Count - 1
  
      Console.WriteLine(NodesCollection(i).Text)
  
  
      k = NodesCollection.Count
  
      Do While k > i
  
        k -= 1
  
        ' Je zwei Nodes ermitteln und Texte vergleichen
        node1 = NodesCollection(i)
        node2 = NodesCollection(k)
        iCompareResult = node1.Text.CompareTo(node2.Text)
  
        ' Falls die Sortierung nicht dem übergebenen Sortierkriterium entspricht:
        If (Ascending = True And iCompareResult > 0) _
           OrElse _
           (Ascending = False And iCompareResult < 0) Then
  
          ' Nodes austauschen
          With NodesCollection
            .Remove(node1)
            .Remove(node2)
            .Insert(i, node2)
            .Insert(k, node1)
          End With
  
        End If
  
      Loop
  
    Next
  
  End Sub

Mathias Schiffer widmet sich als freier Softwareentwickler und Technologievermittler größeren Projekten ebenso wie arbeitserleichternden Alltagslösungen. Seit Jahren gibt er sein Wissen in unzähligen Publikationen auch an andere Entwickler und Entscheider weiter. Sie erreichen ihn per E-Mail an die Adresse Schiffer@mvps.org.