vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#

https://www.vbarchiv.net
Rubrik: Controls · TreeView   |   VB-Versionen: VB4, VB5, VB605.06.03
TreeView-Inhalt schneller löschen

Erstaunlich: Das einzelne Entfernen der TreeView-Node-Objekte geht schneller vonstatten als das Aufrufen der Clear-Methode.

Autor:   Dieter OtterBewertung:  Views:  30.476 
www.tools4vb.deSystem:  Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Wie löscht man alle Einträge eines TreeView-Controls?

Klar, sagen Sie jetzt: Hierfür gibt es doch die Clear-Methode!

' alle Einträge entfernen
TreeView1.Nodes.Clear

Korrekt! ABER: Haben Sie gewußt, dass das einzelne Entfernen der Node-Objekte wesentlich schneller vonstatten geht, als die vorhandene Clear-Methode zu verwenden?

Das glauben Sie nicht?
Also gut... wir demonstrieren das an einem kleinen Beispiel

Erstellen Sie ein neues Projekt und platzieren auf die Form:

  • 1 x TreeView-Control
  • 3 x CommandButton (Command1, Command2 und Command3)
  • 2 x Label (Label1 und Label2)

Beim Klick auf den 1. Button (Command1) füllen wir das TreeView mit 10.000 Einträgen.

Private Sub Command1_Click()
  ' TreeView mit 10.000 Einträgen füllen
  Dim i As Long
 
  Screen.MousePointer = 11
  With TreeView1
    For i = 1 To 10000
      .Nodes.Add , , "k" & CStr(i), "Eintrag " & CStr(i)
    Next i
  End With
  Screen.MousePointer = 0
End Sub

Beim Klick auf den 2. Button (Command2) löschen wir den Inhalt des TreeViews per Clear-Aufruf. Um später einen Vergleich zur Remove-Methode zu haben, stoppen wir die Zeit und zeigen diese dann im Label1 an.

Private Sub Command2_Click()
  Dim nStart As Single
 
  ' Testwert auf einem P4 2,0 GHz, 512 MB RAM
  ' WinXP Prof und VB6 SP5: 305,278 Sek
 
  Screen.MousePointer = 11
  nStart = Timer()
  TreeView1.Nodes.Clear
  Label1.Caption = CStr(Timer() - nStart) & " Sek."
  Screen.MousePointer = 0
End Sub

Starten Sie das Projekt, klicken auf den 1. Button und anschließend auf den 2. Button. Während der TreeView-Inhalt nun gelöscht wird, können Sie getrost einen Kaffee aufsetzen

Beenden Sie das Projekt und fügen nun den Code zum einzelnen Löschen der Node-Objekte ein:

Prvate Sub Command3_Click()
  Dim nStart As Single
 
  ' Testwert auf einem P4 2,0 GHz, 512 MB RAM
  ' WinXP Prof und VB6 SP5: 16,7665 Sek
 
  Screen.MousePointer = 11
  nStart = Timer()
  With TreeView1.Nodes
    Do Until .Count = 0
      .Remove .Count
    Loop
  End With
  Label2.Caption = CStr(Timer() - nStart) & " Sek."
  Screen.MousePointer = 0
End Sub

Starten Sie das Projekt erneut, klicken wieder zunächst auf den 1. Button und anschließend auf den 3. Button. Aber vorsicht: Jetzt bleibt Ihnen nicht mehr soviel Zeit, einen Kaffee aufzusetzen
 

Wie Sie merken, erfolgt das Löschen jetzt wesentlich schneller. Von über 5 Minuten konnten wir uns auf knapp 17 Sekunden steigern.

Durch einen kleinen Trick lassen sich jetzt sogar noch einmal 2 bis 3 Sekunden gutmachen, indem wir die Visible-Eigenschaft des TreeViews vor dem Löschen auf False und danach wieder auf True setzen:

  ' Testwert auf einem P4 2,0 GHz, 512 MB RAM
  ' WinXP Prof und VB6 SP5: 14,0144 Sek
 
  Screen.MousePointer = 11
  nStart = Timer()
  ' TreeView unsichbar machen
  TreeView1.Visible = False
  With TreeView1.Nodes
    Do Until .Count = 0
      .Remove .Count
    Loop
  End With
  ' TreeView wieder sichbar machen
  TreeView1.Visible = True
  Label2.Caption = CStr(Timer() - nStart) & " Sek."
  Screen.MousePointer = 0

Anmerkung:
Bernhard Roos hat uns noch eine Alternative aufgezeigt, mit der sich das Ganze noch einmal erheblich optimieren lässt. Anstelle das TreeView auszublenden (Visible = False) kann man über das Windows API das Neuzeichnen des TreeView-Inhaltes unterdrücken. Diese Vorgehensweise wirkt sich beim Löschen des TreeView-Inhaltes zeitlich noch einmal erheblich aus.

' Benötigte API-Deklarationen
Private Declare Function SendMessage Lib "user32" _
  Alias "SendMessageA" ( _
  ByVal hWnd As Long, _
  ByVal wMsg As Long, _
  ByVal wParam As Long, _
  lParam As Any) As Long
 
Private Const WM_SETREDRAW = &HB
' Fenster-Aktualisierung sperren/entsperren
Private Function LockControl(objX As Object, bLock As Boolean)
  If bLock Then
    ' Disable the Redraw flag for the specified window
    Call SendMessage(objX.hWnd, WM_SETREDRAW, False, 0)
  Else
    ' Enable the Redraw flag for the specified window, and repaint
    Call SendMessage(objX.hWnd, WM_SETREDRAW, True, 0)
    objX.Refresh
  End If
End Function

Aufruf:

' Testwert auf einem AMD Athlon XP 1800, 1,71 GHz, 512 MB RAM
' Win2000 Prof und VB6 SP5:
' 13,58 Sek ohne LockControl
'  4,95 Sek mit  LockControl
 
Screen.MousePointer = 11
nStart = Timer()
 
' Redraw für TreeView abschalten
LockControl TreeView1, True
With TreeView1.Nodes
  Do Until .Count = 0
    .Remove .Count
  Loop
End With
 
' Redraw für TreeView wieder einschalten
LockControl TreeView1, False
Label4.Caption = Format(CStr(Timer() - nStart), "Standard") & " Sek."
Screen.MousePointer = 0



Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
 
Copyright ©2000-2024 vb@rchiv Dieter OtterAlle Rechte vorbehalten.


Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.