AGB  ·  Datenschutz  ·  Impressum  







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

VirtualStringTree und Klasseninstanzen - Node Data finden

Ein Thema von günni0 · begonnen am 16. Apr 2018 · letzter Beitrag vom 17. Apr 2018
Antwort Antwort
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 10: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
 
#2

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 10: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.079 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 10: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
günni0
(Gast)

n/a Beiträge
 
#4

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11: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 11:14 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:26
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;
Da sind wir dann jetzt schon beim ErrorHandling. Aber das ist ok. Alternativ zum Exit könntest du es auch so machen. Sieht eventuell besser aus:
Delphi-Quellcode:
procedure DeleteUserNode(iIndex: Integer);
begin
  if (iIndex > -1) and (iIndex < aVSTDataClasses.Count) then begin
    VST.Clear;
    aVSTDataClasses.Delete(iIndex);
    VST.RootNodeCount := aVSTDataClasses.Count; // re-draws all nodes of VST
  end;
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.
Dazu eine kleine Sache. Das hast du zwar in dem anderen Thread geschrieben, aber da du es jetzt gerade hier ansprichst. Die Änderung der Schriftfarbe solltest du im OnPaintText oder im OnDrawText Event durchführen. OnAfterCellPaint bzw. OnAfterItemPaint sind die Events, die eigentlich nur noch ausgelöst werden, wenn du unabhängig von Text und Images noch etwas in die jeweiligen Cells malen möchtest. Beispielsweise ein Flag, wenn du irgendwann mal Daten im VST geändert hast (mit den Inplace Editoren; da wirst du bestimmt auch irgendwann mal hinkommen).


Anbei mal die Reihenfolge der Events (Auszug aus der Hilde des VST):
Zitat von PaintEvents:
Usually the following paint stages are executed during a paint cycle:
  • before paint (OnBeforePaint)
  • before item paint (OnBeforeItemPaint)
  • before item erase (OnBeforeItemErase)
  • after item erase (OnAfterItemErase)
  • before cell draw (OnBeforeCellPaint)
  • on paint text (string trees only, OnPaintText)
  • after cell draw (OnAfterCellPaint)
  • after item paint (OnAfterItemPaint)
  • after paint (OnAfterPaint)
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#6

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:30
Ich lasse mir zusätzlich zum normalen Node-Text noch eine weitere Zeichenkette ausgeben. Das erledige ich in AfterItemPaint mit TargetCanvas und DrawTextW.
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 11:38
Ich lasse mir zusätzlich zum normalen Node-Text noch eine weitere Zeichenkette ausgeben. Das erledige ich in AfterItemPaint mit TargetCanvas und DrawTextW.
Zeig mal den Auszug. Für Text solltest du dich auf die dafür vorgesehenen Events festlegen. Im normalen GetText Event gibt es auch noch den Unterschied zwischen TextType Normal und TextType Static. Da solltest du evtl. auch mal einen Blick drauf werfen.

Oder eben das DrawText Event. Da bist du vollkommen frei und kannst alles selbst malen was dir in den Sinn kommt. Hauptsache es handelt sich um Text und nicht um irgendwelche Cell spezifischen Dinge.

AfterItemPaint ist dafür eigentlich ungünstig.

EDIT: Vorteil von ttNormal und ttStatic ist, dass der Tree automatisch den Text mit "..." gekürzt abschneidet wenn er nicht passen sollte. Das musst du sonst selbst machen wenn es optisch nach etwas aussehen sollte. Oder du benutzt die Option ColumnSpan, dann zeichnet er den Text in die nächste Column sofern da kein Text steht.

Geändert von Aviator (17. Apr 2018 um 11:40 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 10: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
Antwort Antwort


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 01:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz