Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   VirtualSourceTree selektierte Nodes löschen? (https://www.delphipraxis.net/193074-virtualsourcetree-selektierte-nodes-loeschen.html)

SneakyBagels 17. Jun 2017 20:57


VirtualSourceTree selektierte Nodes löschen?
 
Ich habe folgenden Code geschrieben, um selektierte Nodes zu löschen
Delphi-Quellcode:
var
 Node, NodeTmp: PVirtualNode;
 i: Integer;
begin
 Node := VST.GetFirst;
 while Assigned(Node) do
  begin
   if VST.Selected[Node] then
    begin
     NodeTmp := VST.GetPreviousSibling(Node);

     VST.DeleteNode(Node);

     Node := NodeTmp;
    end;

   Node := VST.GetNextSibling(Node); // ich brauche nur Toplevel Nodes
  end;
end;
Das funktioniert wunderbar. Aber selektiert man nun auch den ersten Node, dann geht das in die Hose.
Ich habe gelesen, dass man den aktuellen Node zwischenspeichern muss, um später GetNextSibling() ausführen zu können.
Denn beim Löschen von Node geht die Referenz auf diesen verloren was zu einer AV führt.

Gibt es eine schönere Möglichkeit durch alles Nodes zu laufen und die selektierten zu löschen? Wichtig ist, dass ich das alles per Hand machen muss.
Einen Einzeiler kann ich, wenn es den gibt, leider nicht verwenden.

0815 wäre eventuell sogar noch... aber ist das noch konform?
Delphi-Quellcode:
var
 Data: TVSTData;
 i: Integer;
 NodeArray: TNodeArray;
begin
 NodeArray := VST.GetSortedSelection(False);
 for i := Low(NodeArray) to High(NodeArray) do
  begin
   VST.DeleteNode(NodeArray[i]); // Node "visuell" löschen
  end;

Aviator 17. Jun 2017 22:37

AW: VirtualSourceTree selektierte Nodes löschen?
 
EDIT: Oha. Ich sollte deinen Beitrag komplett lesen. Da zeigst du ja primzipiell schon die (von dir als 0815 bezeichnet) Lösung mehr oder weniger auf. Schau mal die
Delphi-Quellcode:
DeleteSelectedNodes()
Funktion an. Dort wird das auch gemacht.

Um ehrlich zu sein habe ich noch nie Nodes in einer Schleife löschen müssen. Aber nichts desto trotz verstehe ich diese Aussage nicht:
Zitat:

Zitat von SneakyBagels (Beitrag 1374771)
Gibt es eine schönere Möglichkeit durch alles Nodes zu laufen und die selektierten zu löschen? Wichtig ist, dass ich das alles per Hand machen muss.
Einen Einzeiler kann ich, wenn es den gibt, leider nicht verwenden.

Warum das Rad immer wieder neu erfinden wenn es doch schon Funktionen dafür gibt?
Delphi-Quellcode:
VirtualTreeView1.DeleteSelectedNodes
.

Zur Not schaust du dir die Funktion im SourceCode des Trees an und baust die nach. Ich kann nur wirklich nichts dazu sagen, ob dann wirklich Referenzen verloren gingen. Aber es wäre nur logisch.

Aber schau dir mal die Funktion
Delphi-Quellcode:
TBaseVirtualTree.GetSortedSelection()
an. Die wird auch intern im Tree verwendet wenn du
Delphi-Quellcode:
DeleteSelectedNodes()
aufrufst.

SneakyBagels 17. Jun 2017 22:49

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Warum das Rad immer wieder neu erfinden wenn es doch schon Funktionen dafür gibt?
Ich muss im fertigen Code nicht nur den Eintrag löschen sondern noch ein paar mehr Dinge machen (z.B. ggf. den ObjectList-Eintrag löschen)
Ich möchte neben dem VST noch eine ObjectListe führen, welche die Daten hält.
Denn ab und zu möchte ich nur gewisse Nodes anzeigen, trotzdem aber Zugriff auf alle haben und das geht nur mit einer Liste.

GetSortedSelection mit einer for-Schleife ist interessant und, wie ich finde, besser als eine while-Schleife und Assigned()-Prüfung.
Das funktioniert jetzt erstmal wunderbar.

Ich danke für die Hilfe bisher (auch im anderen Thema).
Mein Umbau von TListView zu VST wird sicher noch viel zeit in Anspruch nehmen und es werden sicher noch mehr Fragen auftauchen.
Alles aber zu seiner Zeit.

jaenicke 17. Jun 2017 23:29

AW: VirtualSourceTree selektierte Nodes löschen?
 
Wenn du mit nicht immer alle anzeigen einen Filter meinst... Dafür gibt es Visible. Damit kannst du Knoten sichtbar und unsichtbar machen und damit extrem schnell live bei der Eingabe filtern.

ConnorMcLeod 19. Jun 2017 09:05

AW: VirtualSourceTree selektierte Nodes löschen?
 
Ich mach das immer so:
  1. alle Nodes durchlaufen
  2. wenn selektiert, dann herausfinden, welche Daten zugrunde liegen und diese Daten vernichten
  3. den Tree neu aufbauen
  4. den vorher gemerkten Treenode wieder fokussieren bzw wenn er gelöscht wurde, dessen nächsten Sibling oder den vorigen Sibling
Das halte ich für am saubersten.

madas 19. Jun 2017 09:36

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374779)
Ich muss im fertigen Code nicht nur den Eintrag löschen sondern noch ein paar mehr Dinge machen (z.B. ggf. den ObjectList-Eintrag löschen)
Ich möchte neben dem VST noch eine ObjectListe führen, welche die Daten hält.

Bei der Objectliste OwnsObjects auf false setzen und im OnFreeNode vom VST das Object der Liste freigeben.
Bei DeleteNode wird dann OnFreeNode aufgerufen.

Uwe Raabe 19. Jun 2017 09:56

AW: VirtualSourceTree selektierte Nodes löschen?
 
Ohne das jetzt probiert zu haben, wäre diese vereinfachte Form deines ursprünglichen Ansatzes nicht vollkommen ausreichend?

Delphi-Quellcode:
  Node := VST.GetFirst;
  while Assigned(Node) do begin
    NodeTmp := VST.GetNextSibling(Node);
    if VST.Selected[Node] then begin
      VST.DeleteNode(Node);
    end;
    Node := NodeTmp;
  end;

SneakyBagels 19. Jun 2017 13:45

AW: VirtualSourceTree selektierte Nodes löschen?
 
(Siehe Edit)

Ungefähr so?
=> ObjectList OwnObjects auf Fale
=> Änderung von Uwe eingebaut

und
Delphi-Quellcode:
procedure TForm2.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
 Data: TVSTData;
 idx: Integer;
begin
 Data := Node.GetData<TVSTData>;

 idx := aVSTDataClasses.IndexOf(Data);
 if idx > -1 then
  aVSTDataClasses.Items[idx].Free;

 // Data.Free;
end;
Danach wird mir noch immer "Count: N ausgegeben" (N = die Anzahl der Nodes vor dem Löschen)
Delphi-Quellcode:
ShowMessage('Count: ' + IntToStr(aVSTDataClasses.Count));



Edit
Dummheit muss bestraft werden.
Delphi-Quellcode:
aVSTDataClasses.Delete(idx);
und nicht
Delphi-Quellcode:
aVSTDataClasses.Items[idx].Free;
.

Aviator 19. Jun 2017 13:58

AW: VirtualSourceTree selektierte Nodes löschen?
 
Auch wenn das
Delphi-Quellcode:
aVSTDataClasses.Items[idx].Free;
an der Stelle nicht passt hier noch ein kleiner Tipp:

Du kannst das
Delphi-Quellcode:
.Items
getrost weglassen und einfach
Delphi-Quellcode:
aVSTDataClasses[idx].Free;
schreiben. Items ist die Standardeigenschaft einer Liste. Somit ist das überflüssig.

Und die Vorteile die du davon hast sind:
  • Keine unnötige Schreibarbeit
  • Übersichtlicherer SourceCode
  • Du kannst so eine Zeile ganz schnell mal für die Benutzung mit einem Array verwenden (auch wenn das jetzt vielleicht nicht so häufig vorkommt)

DeddyH 19. Jun 2017 14:00

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374866)
Dummheit muss bestraft werden.
Delphi-Quellcode:
aVSTDataClasses.Delete(idx);
und nicht
Delphi-Quellcode:
aVSTDataClasses.Items[idx].Free;
.

Und wo wird jetzt die Instanz wieder freigegeben?

SneakyBagels 19. Jun 2017 14:05

AW: VirtualSourceTree selektierte Nodes löschen?
 
Das weiß ich nicht aber beim Schließen der Demo habe ich keinerlei Memory-leaks.
Ich gehe einfach mal davon aus, dass weil ja jetzt das VST die Speicherverwaltung übernimmt, hier die Instanz beim Aufruf von Data.Free freigegeben wird.

DeddyH 19. Jun 2017 14:07

AW: VirtualSourceTree selektierte Nodes löschen?
 
Das ist aber ganz schlecht, wenn Du das nicht weißt. Da können schon kleinere Änderungen am Code entweder zu MemoryLeaks oder zu AVs führen. Ich spreche da aus Erfahrung.

SneakyBagels 19. Jun 2017 14:09

AW: VirtualSourceTree selektierte Nodes löschen?
 
Wie oben geschrieben gehe ich davon aus, dass das VST das jetzt übernimmt, da die ObjectList ja die Daten nicht mehr erbt.
Wenn dem nicht so ist, kannst du mich gerne erschlagen.
Aber selbst wenn ich im OnFreeNode aVSTDataClasses.Delete(idx); weglasse bekomme ich keine Speicherlecks.

Zacherl 19. Jun 2017 15:10

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374873)
Wie oben geschrieben gehe ich davon aus, dass das VST das jetzt übernimmt, da die ObjectList ja die Daten nicht mehr erbt.

Zumindest früher hat der VST das definitiv nicht von alleine gemacht.

Delphi-Quellcode:
IndexOf
ist nebenbei bemerkt keine sehr schnelle Operation und kann bei extrem vielen Nodes deine Performance schon ziemlich verschlechtern. Hat es irgendeinen Grund, warum du die Objekte überhaupt in einer
Delphi-Quellcode:
TObjectList
ablegst? Ich persönlich gehe immer so vor, dass ich beim Einfügen einer Node mein Datenobjekt/Datenrecord mit
Delphi-Quellcode:
Create
erstelle und zuweise. Im
Delphi-Quellcode:
OnFreeNode
hole ich mir dann mit
Delphi-Quellcode:
GetNodeData
den direkten Zeiger auf das Objekt und gebe es dort entsprechend mit
Delphi-Quellcode:
Free
wieder frei.

Oft bietet es sich sogar an mit Records zu arbeiten. Dort musst du zu Begin einmal
Delphi-Quellcode:
NodeDataSize := SizeOf(TDataRecord)
setzen. In diesem Falle verwaltet der VST den Speicher tatsächlich vollkommen von alleine. Lediglich ein
Delphi-Quellcode:
Finalize
im
Delphi-Quellcode:
OnFreeNode
ist teilweise erforderlich (wenn dein Records Strings, Interfaces oder andere managed types enthält).

DeddyH 19. Jun 2017 15:20

AW: VirtualSourceTree selektierte Nodes löschen?
 
Wir drehen uns im Kreis.

SneakyBagels 19. Jun 2017 15:21

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Hat es irgendeinen Grund, warum du die Objekte überhaupt in einer TObjectList ablegst? Ich persönlich gehe immer so vor, dass ich beim Einfügen einer Node mein Datenobjekt/Datenrecord mit Create erstelle und zuweise.
Ich bin mir noch nicht sicher, ob ich TObjectList behalte. Man hört von der einen Seite Zurufe "Ja, verwende es, dann verwaltest du den Speicher selber" und von der anderen Seite das Gegenteil.

Was ist denn jetzt richtiger?
Mir ist nur wichtig, dass ich immer vollen Zugriff auf alle Daten habe. Daher dachte ich, wäre eine ObjectList nicht schlecht.

Zitat:

Zumindest früher hat der VST das definitiv nicht von alleine gemacht.
Kann ich nicht beurteilen. Ich gebe jedenfalls keinerlei Instanzen der in der ObjectListe enthaltenen Daten frei und habe keine Speicherlecks.

Zitat:

IndexOf ist nebenbei bemerkt keine sehr schnelle Operation und kann bei extrem vielen Nodes deine Performance schon ziemlich verschlechtern.
Ich gehe von nicht mehr als 100 und im aller schlechtesten Fall 200 Nodes ohne Children aus.

Delphi-Quellcode:
// ObjectList mit OwnObjects auf FALSE

procedure TForm2.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
 Data: TVSTData;
 idx: Integer;
begin
 Data := Node.GetData<TVSTData>;

 idx := aVSTDataClasses.IndexOf(Data);
 if idx > -1 then
  aVSTDataClasses.Delete(idx);

 Data.Free;
end;
Und so erzeuge ich meine Nodes
Delphi-Quellcode:
type
 TVSTData = class(TObject)
  Col1, Col2, Col3, Col4, Col5, sDescription: string;
  Icon: Byte;
 end;

 TVSTDataClasses = TObjectList<TVSTData>;

var
 aVSTDataClasses: TVSTDataClasses;
...

procedure TForm2.Button1Click(Sender: TObject);
var
 aVSTData: TVSTData;
 i: Integer;
begin
 if not Assigned(aVSTDataClasses) then
  aVSTDataClasses := TVSTDataClasses.Create(False);

 for i := 0 to 5 do
  begin
   aVSTData := TVSTData.Create;
   aVSTData.Col1 := IntToStr(i);
   aVSTData.Col2 := IntToStr(Random(1000));
   aVSTData.Col3 := IntToStr(Random(1000));
   aVSTData.Col4 := IntToStr(Random(1000));
   aVSTData.Col5 := IntToStr(Random(1000));
   aVSTData.Icon := Random(ImageList2.Count - 1);

   if i mod 3 = 0 then
    aVSTData.sDescription := 'Das ist ein ganz langer String - ok so lang ist er nicht!'
   else
    aVSTData.sDescription := '';

   aVSTDataClasses.Add(aVSTData);
  end;

 VST.RootNodeCount := aVSTDataClasses.Count;
end;

Zacherl 19. Jun 2017 15:25

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374882)
Ich gebe jedenfalls keinerlei Instanzen der in der ObjectListe enthaltenen Daten frei und habe keine Speicherlecks.

Sicher? :stupid:
Zitat:

Zitat von SneakyBagels (Beitrag 1374882)
Delphi-Quellcode:
 Data := Node.GetData<TVSTData>;
  ...
 Data.Free;
end;


SneakyBagels 19. Jun 2017 15:27

AW: VirtualSourceTree selektierte Nodes löschen?
 
Ehrlich gesagt - ich weiß es nicht ;)

Am liebsten würde ich die Daten direkt im Node speichern aber das macht man ja wohl auch nicht. Pointer-Gefummel möchte ich nicht mehr.

Zacherl 19. Jun 2017 15:30

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374884)
Ehrlich gesagt - ich weiß es nicht ;)

Ne, also mit dem Codeausschnitt wollte ich dir aufzeigen, dass du die Objekte sehr wohl freigibst :-D Du hast halt zwei Zeiger auf das selbe Objekt. Einmal holst du dir den Zeiger über
Delphi-Quellcode:
GetNodeData
und einmal residiert der Zeiger in der
Delphi-Quellcode:
TObjectList
. Dein
Delphi-Quellcode:
Free
bezieht sich ja aber trotzdem auf das konkrete Objekt.
Delphi-Quellcode:
Data := Node.GetData<TVSTData>;
  ...
 Data.Free;
macht das Gleiche wie

Delphi-Quellcode:
aVSTDataClasses[aVSTDataClasses.IndexOf(Data)].Free

SneakyBagels 19. Jun 2017 15:32

AW: VirtualSourceTree selektierte Nodes löschen?
 
Dann ist das also doch so wie ich vermutet habe.
Deine Methode mit den Records, hat die irgendwelche Vorteile gegenüber einer TObjectList mit einer Klasseninstanze pro Node/Datensatz?

Am Rande. Wenn ich OwnObjects auf False habe, dann kann auch auch genau so gut eine TList nehmen und mit die paar Byates overhead sparen :P

Zacherl 19. Jun 2017 15:36

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374888)
Deine Methode mit den Records, hat die irgendwelche Vorteile gegenüber einer TObjectList mit einer Klasseninstanze pro Node/Datensatz?

Du sparst dir halt das manuelle
Delphi-Quellcode:
Create
/
Delphi-Quellcode:
Free
. Im Grunde eher Geschmackssache.

Die eigentliche Frage ist: benötigst du bidirektionalen Zugriff auf die Daten? Also musst du an irgendeiner Stelle mal die Daten im Datenobjekt modifizieren, ohne die dazugehörige Node zu kennen. In diesem Falle würde die ObjektList bzw. Sinn machen. Trifft das nicht zu, würde ich mir die Liste komplett sparen. Ob du weiter bei Objekten bleibst, oder Records nimmst, macht hier allerdings keinen wirklichen Unterschied.

SneakyBagels 19. Jun 2017 15:39

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zugriff ohne die Nodes zu kennen und ohne auf die visuelle Komponente zugreifen zu müssen, wäre schon nicht schlecht.
Das Schöne daran ist, dass ich in der Liste arbeiten kann und das VirtualStringTree im GetText-Event meine Änderungen übernimmt - und ich habe nicht das VST angefasst.
Das heißt ich glaube ich könnte aus einem TThread heraus Strings in der Liste ändern ohne synchronisieren zu müssen. Naja ist nur eine Vermutung ohne wirklichen Sinn dahinter.

Was mir nur wichtig ist, ist der Zugriff auf die Liste und das Abändern der Daten ohne das VST anfassen zu müssen.

Zacherl 19. Jun 2017 15:43

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von SneakyBagels (Beitrag 1374890)
Das Schöne daran ist, dass ich in der Liste arbeiten kann und das VirtualStringTree im GetText-Event meine Änderungen übernimmt - und ich habe nicht das VST angefasst.

Jap, wenn du solche Funktionalität benötigst, dann bleibe ruhig bei der TObjectList. Bei einigen 100 Nodes sehe ich da auch keine Probleme. Meine Bedenken hatte ich geäußert, da der VST oftmals mit mehreren 10.000 Nodes verwendet wird. Du wirst allerdings nicht umherkommen dir in deinem Datenobjekt noch einen Zeiger zu speichern, der auf die dazugehörige
Delphi-Quellcode:
PVirtualTreeNode
zeigt, damit du nach Datenänderungen von außerhalb noch ein
Delphi-Quellcode:
VST.Update(Data.Node)
aufrufen kannst. Das ist erforderlich, damit die Node neu gezeichnet wird (und somit deine Änderungen visuell übernommen werden). Zumindest wenn du keinen Full Refresh durchführen willst.

himitsu 19. Jun 2017 16:15

AW: VirtualSourceTree selektierte Nodes löschen?
 
Am Ende hat er "kein" Speicherleck, da er ja die TObjectList frei gibt, welche auch alle Ojekte mit nimmt (OwnsObjects=True :?:), welche nicht von dem VT freigegeben wurden.

Problem wäre jetzt, wenn der VT die Ojekte frei gibt, wenn man sie den Nodes bekannt macht
und dann in der ObjectList ungülige Zeiger zurück bleiben, welche man die ObjectList dann natürlich nicht freigeben lassen sollte.

SneakyBagels 19. Jun 2017 16:44

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Am Ende hat er "kein" Speicherleck, da er ja die TObjectList frei gibt, welche auch alle Ojekte mit nimmt (OwnsObjects=True ), welche nicht von dem VT freigegeben wurden.
Ich benutze mittlerweile TList, da ich OwnPbjects der TObjectList eh auf False hatte.

Zitat:

Du wirst allerdings nicht umherkommen dir in deinem Datenobjekt noch einen Zeiger zu speichern, der auf die dazugehörige PVirtualTreeNode zeigt, damit du nach Datenänderungen von außerhalb noch ein VST.Update(Data.Node) aufrufen kannst.
Ein Zeiger auf einen Node, wie soll denn das funktionieren?
Wenn ich raten müsste würde ich vielleicht sowas wie
Delphi-Quellcode:
aVSTDataClasses[Node.Index].aNode := Node;
im InitNode ausführen lassen wobei aNode ein PVirtualNode ist.
Kann es sein, dass du statt VST.Update() eventuell VST.InvalidateNode() meinst?

haentschman 19. Jun 2017 16:53

AW: VirtualSourceTree selektierte Nodes löschen?
 
[meine Meinung]
Bei so vielen Meinungen meine noch dazu...:P
Zitat:

Hat es irgendeinen Grund, warum du die Objekte überhaupt in einer TObjectList ablegst? Ich persönlich gehe immer so vor, dass ich beim Einfügen einer Node mein Datenobjekt/Datenrecord mit Create erstelle und zuweise.
...auch wenn der VST das kann. Damit hällst du die Daten in einem visuellen Control. :roll: Da sagt man heutzutage "Bäh". 8-)
Zitat:

Ich bin mir noch nicht sicher, ob ich TObjectList behalte. Man hört von der einen Seite Zurufe "Ja, verwende es, dann verwaltest du den Speicher selber" und von der anderen Seite das Gegenteil.

Was ist denn jetzt richtiger?
Mir ist nur wichtig, dass ich immer vollen Zugriff auf alle Daten habe. Daher dachte ich, wäre eine ObjectList nicht schlecht.
Definitiv die Objektlist in der Logik. (Trennung der Daten von der GUI)
Sinngemäß: Stell dir mal vor, das dir der VST nicht mehr gefällt und die Daten anders angezeigt werden sollen. An der Datenhaltung ändert sich nichts. Mit der Objektlist ist die Anzeige der Daten (GUI) von der Datenhaltung getrennt. :thumb:


[/meine Meinung]

SneakyBagels 19. Jun 2017 17:25

AW: VirtualSourceTree selektierte Nodes löschen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ist der Source meiner kleinen, super-schlechten Demo. Ich hoffe die Buttons sind trotzdem verständlich und der Code ist nicht all zu schlecht.
Ich habe versucht eure Vorschläge umzusetzen und das ist das Ergebnis.

Zacherl 19. Jun 2017 17:44

AW: VirtualSourceTree selektierte Nodes löschen?
 
Zitat:

Zitat von haentschman (Beitrag 1374903)
[meine Meinung]
Bei so vielen Meinungen meine noch dazu...:P
Zitat:

Hat es irgendeinen Grund, warum du die Objekte überhaupt in einer TObjectList ablegst? Ich persönlich gehe immer so vor, dass ich beim Einfügen einer Node mein Datenobjekt/Datenrecord mit Create erstelle und zuweise.
...auch wenn der VST das kann. Damit hällst du die Daten in einem visuellen Control. :roll: Da sagt man heutzutage "Bäh". 8-)

Puh :-D Achtung: Wall of Text inc: Generell hast du sicherlich recht. Dann aber auch ganz oder gar nicht (sprich über
Delphi-Quellcode:
RootNodeCount
und
Delphi-Quellcode:
OnInitNode
). Manuelles Hinzufügen/Löschen von Nodes (wie es der Threadersteller momentan betreibt) ist nichts anderes als die Modellierung einer Datenstruktur auf Basis des visuellen Controls. Von daher finde ich die Verwendung von Records hier in keinster Weise besser oder schlechter, als die Verwendung von Objekten.
Klar, die Objekte sind theoretisch unabhängig in ihrer
Delphi-Quellcode:
TObjectList
, aber in der Praxis bringt das doch absolut keinen Vorteil, wenn zusätzlich die Struktur nicht auch dort abgebildet wird (was nicht der Fall ist). Möchte ich vom VST auf ein anderes Control umsteigen, dann weiß ich - im Falle eines Baumes - noch lange nicht, in welcher Hierachie die einzelnen Objekte anzuordnen sind. Und selbst, wenn es nur eine einfache Liste ist, wiederspricht das manuelle Hinzufügen/Löschen von Nodes immer noch dem "virtual" Paradigma und degradiert das Control im Grunde zu einem normalen List/TreeView. Deshalb gewinnt in meiner Abwägung hier das KISS Prinzip gegenüber der absolut korrekten Trennung von Daten und GUI.

Noch als Ergänzung:
Ich habe mich in letzter Zeit recht intensiv mit der Abbildung von Datenstrukturen auf (virtuellen) Bäumen beschäftigt. Hierbei ist es auch so, dass ich eine Baumstruktur in einer seperaten Datenstruktur vorliegen habe - komplett unabhängig von visuellen Controls, ganz wie es sich gehört. Jetzt habe ich versucht diese Struktur visuell abzubilden und mich in diesem Zusammenhang mit der
Delphi-Quellcode:
TcxVirtualTreeList
beschäftigt. Vielleicht liegt es an meiner mangelnden Erfahrung mit dieser speziellen Komponente, aber die Geschichte hatte diverse Tücken, wenn man einzelne Objekte aus der Datenstruktur entfernen wollte.
Letztlich bin ich dann auch wieder weg vom virtuellen Prinzip und habe stattdessen meine Datenstruktur um Events (CreateNode, InsertNode, RemoveNode, DestroyNode) erweitert. In den entsprechenden Event-Handlern implementiere ich dann AddChild, Move und Delete auf dem gewünschten visuellen Control. Das wäre zumindest eine Möglichkeit der korrekten Trennung; wobei ich persönlich es in diesem Falle wie gesagt einfach für Overkill halte.

SneakyBagels 19. Jun 2017 18:05

AW: VirtualSourceTree selektierte Nodes löschen?
 
Das lässt mich nachdenken.

Wäre es möglich wenn sich beide Parteien meine Demo ansehen und dann entscheiden ob das so in Ordnung ist?
Mein Ziel ist es, dass ich von verschiedenen Stellen im Programm Zugriff auf die Daten habe.
Aktuell ist es ECHT FIES! Ich schnappe mir die TreeView-Caption, öffne eine Ini-Datei, lade die Section und lese Daten aus.
Das wäre mit VST mit und/oder ohne TList nicht mehr der Fall.

Fritzew 20. Jun 2017 17:21

AW: VirtualSourceTree selektierte Nodes löschen?
 
Ich denke Du kannst wirklich eine TObjectlist benutzen,
aber dann ist es wichtig festzulegen wem die Daten "gehören". In diesem Fall der Liste.


Änderungen die ich gemacht habe:

Typ geändert:

TVSTDataClasses = TObjectList<TVSTData>;

das erzeugen von aVSTDataClasses habe ich in das FormCreate verschoben

Delphi-Quellcode:
  ReportMemoryLeaksOnShutdown := True;
  aVSTDataClasses := TVSTDataClasses.Create;
Im Button1Click habe ich das erzeugen der Liste entfernt.

Zusätzlich FormDestroy

Delphi-Quellcode:
 procedure TForm2.FormDestroy(Sender: TObject);
begin
   aVSTDataClasses.free;
end;
Das freenode umgebaut auf:

Delphi-Quellcode:
 procedure TForm2.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
 // Das aber nur wenn wirklich die Daten aus der Liste weg sollen!!!!
 aVSTDataClasses.remove(node.GetData<TVSTData>);
end;
Button3Click:
Delphi-Quellcode:
 procedure TForm2.Button3Click(Sender: TObject);
begin
 // Hier muss auf jeden Fall der VST gecleared werden
 VST.Clear;

 // Jetzt sollte aVSTDataClasses.count 0 sein wenn im VSTFreeNode der Eintrag gelöscht wird

 // Nur notwendig wenn im VSTFreeNode die nodes nicht freigegeben werden
 aVSTDataClasses.Clear;
end;

Umbau des Button5Click
Delphi-Quellcode:
 procedure TForm2.Button5Click(Sender: TObject);
var
 Node, NodeTmp: PVirtualNode;
begin
 Node := VST.GetFirstSelected;
 while Assigned(Node) do
  begin
   NodeTmp := VST.GetNextSelected(Node);

    VST.DeleteNode(Node);

   Node := NodeTmp;
  end;
end;

SneakyBagels 20. Jun 2017 17:52

AW: VirtualSourceTree selektierte Nodes löschen?
 
Mh auch nicht schlecht.

Heißt also, die Daten werden von der Liste verwaltet und man braucht nur eine einzige Zeile aufrufen, um einen Node + Daten zu löschen.

DeddyH 20. Jun 2017 18:02

AW: VirtualSourceTree selektierte Nodes löschen?
 
Ja, davon reden wir schon seit Tagen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz