Entwickler-Ecke

LCL-Komponenten - VirtualStringTree "live" aktualisieren


Martok - So 27.09.15 20:20
Titel: VirtualStringTree "live" aktualisieren
Hallo,

zur Darstellung von Baumdaten (mehrere 100k Knoten) nutze ich einen VirtualStringTree. Die Daten sind Teilsummen (Größe, Anzahl...) über einem Dateisystem. Hier wird also einmal komplett alles gescannt. Beispiel:
user defined image

Während das Dateisystem gescannt wird, möchte ich die Daten "live" aktualisierend anzeigen. Was sich ändern kann, sind also die Spaltenwerte, HasChildren (genau einmal, wenn das Verzeichnis das erste mal besucht wird) und die Sortierung der Anzeige. Knoten können nicht verschwinden oder sich die Anzahl der Kindknoten nachträglich ändern.

Die Knoten initalisiere ich momentan per OnInitNode, OnInitChildren (für die Anzahl) und OnGetText, sortiert wird mit OnCompareNodes.

Während dem Scan lasse ich regelmäßig die sichtbaren Knoten neu initialisieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
  node:= vstResults.GetFirstVisible;
  while node <> nil do begin
    vstResults.ReinitNode(node,false);
    node:= vstResults.GetNextVisible(node);
  end;

Ab und zu passiert es jetzt, dass Knoten nicht mitbekommen, dass sie Kindknoten haben (Beispielbild [http://puu.sh/kqer0/93df81ab21.jpg] von user profile iconTeekeks - man beachte: die Spalten enthalten die richtigen Daten, der Knoten wurde also aktualisiert, hat aber keine Kinder bekommen). Dieser Bug ist sehr selten.
Selbst wenn das alles funktioniert, gibt es ein furchtbares Geflacker (durch die Sortierung, vermute ich) und die Expanded-Zustände der Knoten werden auch weggeworfen. Was ich also eigentlich bräuchte, ist ein "Teil-Reinit".

Wie macht man sowas sauber, was mache ich falsch? Mit VirtualTrees in der wirklich virtuellen Betriebsweise, also ohne alle Nodes rekursiv zu initialisieren, habe ich recht wenig Erfahrung. Ein VirtualDrawTree löst auch nur das halbe Problem, da kann die fehlende HasChildren-Weitergabe noch genauso passieren.

Viele Grüße,

Sebastian

PS: LCL-Sparte, weil es hier um den LCL-Port von VirtualTrees 5.4.1 geht. Sollte aber egal sein.


Delete - Mo 28.09.15 14:07

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Ab und zu passiert es jetzt, dass Knoten nicht mitbekommen, dass sie Kindknoten haben ...

Das kann eigentlich nur daran liegen, daß du die Childs nicht im VirtualStringTree (VST) einträgst. Mit anderen Worten: Ich konnte im VST bislang nicht beobachten, daß ChildNodes, die ich angelegt habe, nicht angezeigt werden ... allerdings kann ich keine Erfahrung mit VST und Lazarus vorweisen und daher nicht beurteilen, ob ein solcher Bug in der Lazarus-Version existiert. Natürlich hatte ich auch schon ähnliche Phänomene mit dem VST, aber das lag immer und ohne Ausnahme an mir: den Fehler hatte ich also immer selbst zu verantworten.

Irgendwo in deinem Code liest du doch das Dateisystem rekursiv aus. Genau dort würde ich noch einmal genau nachforschen, ob denn wirklich immer alle Unterverzeichnisse und Dateien im VST eingetragen werden. Ansonsten kann ich ohne weiteren Code nicht viel mehr dazu sagen ...


Martok - Mo 28.09.15 17:22

Wie ich oben schrob:
user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
(Beispielbild [http://puu.sh/kqer0/93df81ab21.jpg] von user profile iconTeekeks - man beachte: die Spalten enthalten die richtigen Daten, der Knoten wurde also aktualisiert, hat aber keine Kinder bekommen).

Es wird nur .HasChildren nicht übernommen (und dementsprechend auch OnInitChildren nicht aufgerufen).


Delete - Di 29.09.15 14:50

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Es wird nur .HasChildren nicht übernommen (und dementsprechend auch OnInitChildren nicht aufgerufen).

Du meinst also, du überprüfst einen Knoten, ob er Unterknoten hat, und der Test verläuft trotz vorhandener Childs negativ? Mir ist mal was Ähnliches passiert, da hatte ich einfach den falschen Knoten geprüft. Hast du dich denn auch wirklich davon überzeugt, daß du den richtigen Knoten abfragst?