teilweises Sortieren von TreeView



  • Hallo! Ich habe hier folgende Funktion zum sortieren einer Ebene von einem TreeView. Das dauert aber jetzt schon ein paar Sekunden für ~100 Einträge(auf Ebene 0) und ist damit deutlich zu lang.
    Das von Haus aus mitgebrachte TreeView.Sort() ist schneller, wobei dieses sogar alle Unterknoten(~5600 Einträge) sortiert. Wo kann ich noch optimieren?

    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 k As Integer
            Dim iCompareResult As Integer
    
            For i As Integer = 0 To NodesCollection.Count
                k = NodesCollection.Count
                Do While k > i
                    k -= 1
                    node1 = NodesCollection(i)
                    node2 = NodesCollection(k)
                    iCompareResult = node1.Text.CompareTo(node2.Text)
    
                    If (Ascending = True And iCompareResult > 0) OrElse _
                       (Ascending = False And iCompareResult < 0) Then
                        With NodesCollection
                            .Remove(node1)
                            .Remove(node2)
                            .Insert(i, node2)
                            .Insert(k, node1)
                        End With
                    End If
                Loop
            Next
        End Sub
    


  • Antworten in c# sind auch ok.



  • Quicksort, Mergesort, Heapsort ... irgendeinen Algorithmus der nicht so langsam wie Bubblesort ist.
    Das NET-Framework bietet aber schnelle Sortieralgorithmen. Muss man nicht selbst implementieren.



  • Finde nur was für Arrays und Listen.
    Eine ferige Methode, die einen TreeNodeCollection frisst, finde ich nicht.
    Muss ich das vorher konvertieren?



  • Dein Performancefresser ist

    With NodesCollection
        .Remove(node1)
        .Remove(node2)
        .Insert(i, node2)
        .Insert(k, node1)
    End With
    

    Vertausche am besten nur den Text (und evtl. andere benötigte Eigenschaften).
    Du solltest auf jeden Fall BeginUpdate()/EndUpdate() zusätzlich verwenden, damit nicht jedesmal der Tree neu gezeichnet wird.


  • Administrator

    Dudeldu schrieb:

    Finde nur was für Arrays und Listen.
    Eine ferige Methode, die einen TreeNodeCollection frisst, finde ich nicht.
    Muss ich das vorher konvertieren?

    Sollte so oder so ähnlich funktionieren:

    class TreeNodeComparer
      : IComparer
    {
      public int Compare(object left, object right)
      {
        return ((TreeNode)left).Text.CompareTo(((TreeNode)right).Text);
      }
    }
    
    // ...
    
    public void SortNodes(TreeViewCollection collection)
    {
      ArrayList
        .Adapter(collection)
        .Sort(new TreeNodeComparer());
    }
    

    TreeNodeComparer kannst du natürlich so erweitern, wie du es benötigst. Ich würde aber den Tipp von Th69 trotzdem noch verfolgen: BeginUpdate() / EndUpdate() . Zusätzlich stellt sich die Frage, ob man überhaupt die TreeNodes sortieren sollte oder nicht besser die Daten, welche man dann auf die TreeNodes übersetzt?

    Grüssli



  • Ok, danke erstmal.
    BeginUpdate()/EndUpdate() hab ich schon drin.

    @Th69 Ich möchte ja nur den Knoten auf Ebene 0 samt Unterknoten "umhängen", deshalb kann ich nicht einfach den Text tauschen, sondern müsste alle Texte der Unterknoten mit umtauschen und evtl. neue hinzufügen/entfernen.

    @Dravere
    Das werde ich gleich mal ausprobieren und geb dann Feedback.



  • Besten dank!
    Funktioniert wunderbar 🙂


Log in to reply