Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte » 

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 21: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 23: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 23: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 18. Jun 2017 00: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 10: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 10: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 10: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 14: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 14: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 15: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?


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:27 Uhr.
Seite 1 von 4  1 23     Letzte » 

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