.NET: Status einer TreeView Speichern und Laden
Wenn man mit TreeView Steuerelementen arbeitet kommt man irgendwann nicht drumherum diese zu speichern. Dieses Thema habe ich ja schon in 2 Beiträgen besprochen und eine Klasse zur Verfügung gestellt, welche die TreeView in einer XML Datei speichert.
Das Problem ist nur, wenn ich den Inhalt der TreeView wieder geladen habe möchte ich normalerweise auch, dass die Ordner, die beim Schließen des Programms geöffnet waren auch nach dem Laden wieder offen sind. Das spart eine menge Zeit und ist einfach bequemer.
Bild 1: Das Demoprojekt nach dem Laden des Treenode-Zustands
Leider bietet uns die TreeView Klasse keine Möglichkeit dies schnell und einfach zu lösen. Darum muss eine eigene Funktion her!
Ich bin diese Problemstellung folgendermaßen angegangen: Ich durchlaufe die komplette TreeView und schaue, welche Äßte geöffnet sind. Jedesmal wenn ich auf einen Ast stoße, der offen ist notiere ich mir eine "1" ansonsten eine "0".
Irgendwann habe ich dann eine Variable mit lauter Nullen und Einsen. Diese Speichere ich in einer Datei, die ich dann beim Laden des Programms wieder durchlaufe und die Knoten wieder öffne.
Das ganze sieht dann so aus: (Speichern)
Public Function saveNodeState(ByVal tn As TreeNode, Optional ByVal retv As String = "") As String
Dim retVal As String = retVal & retv
'Jede Node in der übergebenen Node durchgenen
For Each tnn As TreeNode In tn.Nodes
'Prüfen, welche Nodes geöffnet sind und diesen zustand speichern
' 1 => offen
' 0 => geschlossen
If tnn.Nodes.Count > 0 Then
If tnn.IsExpanded Then
retVal = retVal & "1"
Else
retVal = retVal & "0"
End If
'Hats der node weitere "kinder" ist es ein ordner
'also diese node rekursiv an sich selbst übergeben!
retVal = saveNodeState(tnn, retVal)
End If
Next
Return retVal
End Function
Und Laden:
Public Function loadNodeState(ByVal tn As TreeNode, Optional ByVal settings As String = "")
'Jede Node in der übergebenen Node durchgenen
'Den Zustand der Nodes wiederherstellen (Offen oder geschlossen)
For Each tnn As TreeNode In tn.Nodes
If tnn.Nodes.Count < 1 Then
'Wenn der Node keine Kinder hat überspringen
Else
'Prüfen, ob der Node früher geöffnet war
If settings <> "" Then
If settings.Substring(0, 1) = "1" Then
tnn.Expand()
End If
settings = settings.Substring(1, settings.Length - 1)
End If
'Hat der node weitere "kinder" ist es ein ordner
'also diesen node rekursiv an sich selbst übergeben!
settings = loadNodeState(tnn, settings)
End If
Next
Return settings
End Function
Für beide Funktionen ist ein rekursiver Aufruf von Nöten, da man auch die Unterordner durchlaufen muss! Das ganze ist im Prinzip sehr einfach und funktioniert wunderbar!
Wenn ihr auch (bessere) Ideen habt wie man das bewerkstelligen könnte bitte als Kommentar posten.
Dazu habe ich auch ein Kleines Demoprojekt angefertigt: Download
Oktober 13th, 2010
Ich finde die Functionen super! Meinst Du, Du kannst mir das für Access umschreiben? Ich kriges nicht hin.
Gruß Guido
Oktober 14th, 2010
Hallo Guido,
woran hapert es denn bei dir?
Grüße Basti
Dezember 30th, 2010
Funktioniert prima, ich habe zusätzlich noch ein
.ensurevisible eingebaut, damit die geöffneten
Nodes auch gleich wieder sichtbar sind:
If settings “” Then
If settings.Substring(0, 1) = “1″ Then
tnn.Expand()
‘* änderung – auch sichtbar machen
tnn.EnsureVisible()
End If
settings = settings.Substring(1, settings.Length – 1)
End If
Danke für das Grundgerüst!