AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein VirtualStringTree und Klasseninstanzen - Node Data finden

VirtualStringTree und Klasseninstanzen - Node Data finden

Ein Thema von günni0 · begonnen am 17. Apr 2018 · letzter Beitrag vom 17. Apr 2018
Antwort Antwort
Seite 2 von 3     12 3   
günni0
(Gast)

n/a Beiträge
 
#11

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 10:46
Ich mache gerade ein Beispiel. 10 Minuten noch.

So ganz klappt es noch nicht. Speziell wenn man erst den Button Node mit Idx 2 löschen drückt und dann Node Peter Wurst löschen.

Mein Ziel wäre es, die Referenz auf Node wegzubekommen und die Möglichkeit zu haben, das wenn ich eine Klasseninstanz lösche, auch gleich der Node mit weg ist.
Aktuell ist es ja so, dass ich den Node löschen muss. Und das geht nur mit einer Referenz da drauf. Aber ihr seht, mein Code ist wie Pasta ... nix funktioniert.
Angehängte Dateien
Dateityp: zip VST.zip (2,2 KB, 4x aufgerufen)

Geändert von günni0 (17. Apr 2018 um 10:58 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#12

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:09
Das nächste Mal bitte als Projekt

Mach mal folgendes, aber bedenke, dass das jetzt nur eine Lösung für deine Vorgehensweise hier ist. Und bitte alles beachten. Ich hänge bewusst die Datei nicht an, damit du die Änderungen auch selbst einbauen musst und hoffentlich auch verstehst:

Delphi-Quellcode:
procedure TForm2.Button2Click(Sender: TObject);
begin
 VST.Clear;
 DeleteNode(2); // Daten anhand des Index löschen. 2 ist nicht der absolute Index sondern der, der in Button1Click gesetzt wird
 VST.RootNodeCount := aVSTDataClasses.Count;
end;

procedure TForm2.Button3Click(Sender: TObject);
begin
  VST.Clear;
  DeleteNode('Peter Wurst'); // Daten anhand eines Nutzernamens löschen
  VST.RootNodeCount := aVSTDataClasses.Count;
end;
Delphi-Quellcode:
procedure DeleteNode(iIndex: Integer); overload;
//var
// Node: PVirtualNode;
begin
  aVSTDataClasses.Delete(iIndex);

// Node := FindUserNodeByIndex(iIndex);
// if Assigned(Node) then
// Form2.VST.DeleteNode(Node);
end;
Delphi-Quellcode:
procedure TForm2.FormCreate(Sender: TObject);
var
 Column: TVirtualTreeColumn;
 i: Byte;
begin
 ReportMemoryLeaksOnShutdown := True;
 
 ...

 VST.OnInitNode := VSTInitNode;
// VST.OnFreeNode := VSTFreeNode; // <--- WICHTIG! ENTFERNEN!
 VST.OnGetText := VSTGetText;
end;
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#13

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:18
Ok Moment ganz langsam für meinen alten Kopf.
Heißt das jetzt, dass du mit 2, 3 Zeilen Umstellung das so gemacht hast, dass man jetzt eine Klasseninstanz löscht, das Node verschwindet (man löscht ja alle mit Clear) und alles neugezeichnet wird?
Wird das Neuzeichnen durch das Setzen von RootNodeCount ausgelöst?

Das ist dann ja genau das was TiGü meinte, nur habe ich es leider nicht ganz verstanden.

Geändert von günni0 (17. Apr 2018 um 11:26 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#14

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:23
Ja das ist genau das was TiGü meinte.

Dein größter Fehler war eben (wie ich in meinem vorletzten Post schrieb), dass du das OnFreeNode Event implementiert hast. OnFreeNode gibt die Daten die an die Node gebunden sind frei. Zumindest, wenn du das in dem Event so festgelegt hast.

Und da du im OnFreeNode() die Instanz per Remove() aus der ObjectList gelöscht hast, wurde die natürlich auch beim leeren des Trees mit VST.Clear() ebenfalls gelöscht.

Das Neuzeichnen des Trees wird durch das setzen von RootNodeCount, aber auch durch das vorhergehende löschen der Nodes mit VST.Clear() ausgeführt.
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#15

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:26
TiGü schriebe, dass es schlechtes Design wäre sich eine Referenz auf Node zu halten.

Ich habe eine Funktion die sieht so aus
Delphi-Quellcode:
function FindUserNodeByIndex(iIndex: Integer): PVirtualNode;
var
 i: Integer;
begin
 Result := nil;
 for i := 0 to aVSTDataClasses.Count - 1 do
  if aVSTDataClasses[i].Index = iIndex then
   begin
    Result := aVSTDataClasses[i].aNode;
    Break;
   end;
end;
Ist von sowas dann abzuraten?

Die markierte Zeile unten kann dann vermutlich auch weg
Delphi-Quellcode:
procedure TForm2.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
 Node.SetData<TVSTData>(aVSTDataClasses[Node.Index]);
 aVSTDataClasses[Node.Index].aNode := Node; // ----------------------------------------------
end;
So würde ich dann beispielsweise den Text eines Properties ändern ohne die Node-Referenz
Delphi-Quellcode:
 aVSTDataClasses[5].sUserName := 'XXXXXXXXXXXXXX';

 VST.Invalidate; // InvalidateNode(aVSTDataClasses[5].aNode);
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#16

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:27
Habe dein Edit leider erst nach meinem Post gesehen.

TiGü schriebe, dass es schlechtes Design wäre sich eine Referenz auf Node zu halten.

ich habe eine Funktion die sieht so aus
Delphi-Quellcode:
function FindUserNodeByIndex(iIndex: Integer): PVirtualNode;
var
 i: Integer;
begin
 Result := nil;
 for i := 0 to aVSTDataClasses.Count - 1 do
  if aVSTDataClasses[i].Index = iIndex then
   begin
    Result := aVSTDataClasses[i].aNode;
    Break;
   end;
end;
Ist von sowas dann abzuraten?

Die markierte Zeile unten kann dann vermutlich auch weg
Delphi-Quellcode:
procedure TForm2.VSTInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
begin
 Node.SetData<TVSTData>(aVSTDataClasses[Node.Index]);
 aVSTDataClasses[Node.Index].aNode := Node; // ----------------------------------------------
end;
Auch da hat er Recht wenn er sagt, dass das schlechtes Design ist. Die Daten sollten generell nie etwas von dem anzuzeigenden Control wissen. Wenn später irgendwelche Dinge mit den Daten passieren sollen, dann musst du das auf Datenebene machen. Und nicht dadurch, dass du durch die Nodes iterierst.
Genau so ist das auch umgekehrt. Wenn du die Daten aktualisiert, dann reicht ein VST.Invalidate(). Wenn Daten hinzugefügt oder gelöscht werden, dann solltest du die Daten auch im VST aktualisieren - sprich löschen und neu erstellen. Das ist das, was TiGü mit konsistentem Zustand meinte. Deine Daten im VST passen immer 100% zu den Daten in deiner ObjectList.


EDIT: Oh je. Jetzt ist es kein Edit mehr
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#17

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:32
Zitat:
Auch da hat er Recht wenn er sagt, dass das schlechtes Design ist.
Oh ich wollte nicht, dass ihr mich falsch versteht. Ich stelle eure aller Kenntnisse nicht in Frage.
Ich frage nur in die Runde.

Zitat:
Wenn Daten hinzugefügt oder gelöscht werden, dann solltest du die Daten auch im VST aktualisieren - sprich löschen und neu erstellen.
Also Clear aufrufen und RootNodeCount setzen. Dass das Setzen von RootNodeCount alles neuzeichnet, das muss man erst einmal wissen. Denn der Name sagt was komplett anderes.
Mit erstellen meinst du ja RootNodeCount setzen denke ich doch?

Zitat:
Die Daten sollten generell nie etwas von dem anzuzeigenden Control wissen
Den Satz werde ich mir merken.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#18

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:45
Wie ich sehe, nimmt das langsam vernünftige Formen an.
Höre auf das, was Aviator sagt. Er ist sehr erfahren mit dem VST.

Alternativ zum RootNodeCount und OnInitNode-Eventhandler kannst du natürlich auch versuchen mit AddChild zu arbeiten.
Delphi-Quellcode:
 
  // PseudoCode
  for deinTyp in deinerListe do
  begin
    vst.AddChild(nil, deinTyp);
  end;
Kommt auf das gleiche hinaus, aber vielleicht verstehst du das in zwei Monaten noch, wenn du dir den Code nochmal anguckst.
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.610 Beiträge
 
Delphi 10.3 Rio
 
#19

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:50
Zitat:
Auch da hat er Recht wenn er sagt, dass das schlechtes Design ist.
Oh ich wollte nicht, dass ihr mich falsch versteht. Ich stelle eure aller Kenntnisse nicht in Frage.
Ich frage nur in die Runde.
Ich habe das auch nicht falsch verstanden. Ich wollte nur die Aussage von TiGü untermauern und damit sagen, dass er das bereits korrekt gesagt hat.

Zitat:
Wenn Daten hinzugefügt oder gelöscht werden, dann solltest du die Daten auch im VST aktualisieren - sprich löschen und neu erstellen.
Also Clear aufrufen und RootNodeCount setzen. Dass das Setzen von RootNodeCount alles neuzeichnet, das muss man erst einmal wissen. Denn der Name sagt was komplett anderes.
Mit erstellen meinst du ja RootNodeCount setzen denke ich doch?
Ja, das meine ich damit. Ich finde es ja schonmal gut, dass du überhaupt RootNodeCount nutzt. Das ist auch die richtige Vorgehensweise. Viele fangen mit AddChild() an und müssen sich dann irgendwann später wieder umstellen.

Wie ich sehe, nimmt das langsam vernünftige Formen an.
Höre auf das, was Aviator sagt. Er ist sehr erfahren mit dem VST.
Danke für das Lob.

Alternativ zum RootNodeCount und OnInitNode-Eventhandler kannst du natürlich auch versuchen mit AddChild zu arbeiten.
Delphi-Quellcode:
 
  // PseudoCode
  for deinTyp in deinerListe do
  begin
    vst.AddChild(nil, deinTyp);
  end;
Kommt auf das gleiche hinaus, aber vielleicht verstehst du das in zwei Monaten noch, wenn du dir den Code nochmal anguckst.
Bloß nicht. Zum Glück habe ich vorm Absenden deinen Post, der zwischenzeitlich erstellt wurde, nochmal gelesen.

Er ist mit RootNodeCount schon auf dem richtigen Weg. AddChild() ist zwar anfängerfreundlicher, aber wenn er sowieso schon richtig angefangen hat, dann sollten wir ihn auf keinen Fall auf die falsche Spur locken.

Anbei mal noch ein Auszug aus dem Source der VirtualTreeView Komponente (Hervorhebung von mir):

Zitat von VirtualTreeView Source:
function TBaseVirtualTree.AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode;

// Adds a new node to the given parent node. This is simply done by increasing the child count of the
// parent node. If Parent is nil then the new node is added as (last) top level node.
// UserData can be used to set the first sizeof(Pointer) bytes of the user data area to an initial value which can be used
// in OnInitNode and will also cause to trigger the OnFreeNode event (if <> nil) even if the node is not yet
// "officially" initialized.
// AddChild is a compatibility method and will implicitly validate the parent node. This is however
// against the virtual paradigm and hence I dissuade from its usage.
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#20

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 12:11
Höre auf das, was Aviator sagt. Er ist sehr erfahren mit dem VST. Ich höre auf euch beide

Eine Sache habe ich eben noch hinzugefügt

aus
Delphi-Quellcode:
procedure TForm2.Button2Click(Sender: TObject);
begin
 VST.Clear;
 DeleteNode(2); // Daten anhand des Index löschen. 2 ist nicht der absolute Index sondern der, der in Button1Click gesetzt wird
 VST.RootNodeCount := aVSTDataClasses.Count;
end;
wird

Delphi-Quellcode:
procedure DeleteUserNode(iIndex: Integer);
begin
 if iIndex > aVSTDataClasses.Count - 1 then // ---------------- neu
  Exit;

 VST.Clear;
 aVSTDataClasses.Delete(iIndex);
 VST.RootNodeCount := aVSTDataClasses.Count; // re-draws alle nodes of VST
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
 DeleteNode(2);
end;
Zitat:
Alternativ zum RootNodeCount und OnInitNode-Eventhandler kannst du natürlich auch versuchen mit AddChild zu arbeiten.
Zitat:
Bloß nicht.
Habe es eben dennoch mal ausprobiert.
Mein erstes Erlebnis waren Nodes die nicht richtig gezeichnet wurden, wenn man das AfterItemPaint-Event nutzt. Aber das war nur minimal und nicht weiter schlimm und auch sofort wieder weg, sobald man mit der Maus über den Node gefahren ist.

Geändert von günni0 (17. Apr 2018 um 12:14 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:31 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