Rubrik: Controls · TreeView | VB-Versionen: VB4, VB5, VB6 | 05.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 Otter | Bewertung: | Views: 30.476 |
www.tools4vb.de | System: 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