Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Datenhaltung mit VirtualStringTree und Trennung der Businesslogik (https://www.delphipraxis.net/200152-datenhaltung-mit-virtualstringtree-und-trennung-der-businesslogik.html)

DieDolly 1. Apr 2019 19:06

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Davon würde ich gerne mehr erfahren wollen? Also der Grund, warum man nicht AddChild verwenden soll, ist nur die Performance oder gibt es noch andere Gründe? Gab es Performancetests dazu?
Wenn man eine Liste benutzt und die Daten dort hinterlegt, die das VST dann auslesen kann, hat man einen großen Vorteil. Die Daten sind vom Control getrennt und man kann auf sie zugreifen, ohne auf das Control zugreifen zu müssen. Aus Threads heraus ist das eine feine Sache.

Aviator 1. Apr 2019 21:52

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Zitat von jus (Beitrag 1429272)
Davon würde ich gerne mehr erfahren wollen? Also der Grund, warum man nicht AddChild verwenden soll, ist nur die Performance oder gibt es noch andere Gründe? Gab es Performancetests dazu?

Ein Grund ist sicherlich die Performance. Der Tree initialisiert gewisse Dinge erst dann, wenn sie benötigt werden. Und das passiert nur, wenn
Delphi-Quellcode:
RootNodeCount
bzw.
Delphi-Quellcode:
ChildCount
benutzt wird. Bei AddChild hingegen wird die Node direkt initialisiert. Zudem ist es mit
Delphi-Quellcode:
RootNodeCount
soweit ich weiß auch möglich, die NodeDaten erst dynamisch und zu dem Zeitpunkt zu laden an dem sie benötigt werden (eben virtuell).

Zum Schluss noch ein kleiner Auszug aus dem VirtualTreeView SourceCode zur
Delphi-Quellcode:
AddChild()
Methode.

Zitat:

Zitat von VirtualTreeView
// 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.


Codehunter 2. Apr 2019 07:10

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Zitat von Aviator (Beitrag 1429287)
Zudem ist es mit
Delphi-Quellcode:
RootNodeCount
soweit ich weiß auch möglich, die NodeDaten erst dynamisch und zu dem Zeitpunkt zu laden an dem sie benötigt werden (eben virtuell).

Also das wird ja schon durch das von dir zitierte Komment widerlegt :-) Genauer gesagt durch die überladene Methode AddChild, die es mit und ohne UserData gibt.

Ich will hier ja keinesfalls für die Verwendung von AddChild sprechen. Aber es gibt eben Anwendungsfälle, wo man mit dem Weg über ChildCount erhebliche Verrenkungen machen muss. Als grobe Orientierung kann man evtl. die Anzahl der zu erzeugenden Nodes nehmen. Oder auch die Frage, ob man mit Listen arbeitet oder nicht.

Außerdem möchte ich noch darauf hinweisen, dass es die Methoden BeginUpdate und EndUpdate gibt. Dadurch kann man Initialisierungen direkt durch AddChild reduzieren. Außerdem lässt man den Rechenaufwand durch Initialisierung mit dem Gebrauch von ChildCount nicht einfach weg. Vielmehr geschieht er dann "wenn er gebraucht wird". Was in der Regel bedeutet, dass er bei der Visualisierung initialisiert wird. Das kann sogar von Nachteil sein, wenn die Initialisierung rechenintensiv ist und der Anwender viel vom Scrolling Gebrauch macht.

Aviator 2. Apr 2019 21:28

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Zitat von Codehunter (Beitrag 1429298)
Zitat:

Zitat von Aviator (Beitrag 1429287)
Zudem ist es mit
Delphi-Quellcode:
RootNodeCount
soweit ich weiß auch möglich, die NodeDaten erst dynamisch und zu dem Zeitpunkt zu laden an dem sie benötigt werden (eben virtuell).

Also das wird ja schon durch das von dir zitierte Komment widerlegt :-) Genauer gesagt durch die überladene Methode AddChild, die es mit und ohne UserData gibt.

Please elaborate! Also diesen Satz von dir verstehe ich nicht so ganz. Habe mir den jetzt 3 mal durchgelesen und bin noch so schlau wie am Anfang. :oops:

DieDolly 2. Apr 2019 21:38

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Zudem ist es mit RootNodeCount soweit ich weiß auch möglich, die NodeDaten erst dynamisch und zu dem Zeitpunkt zu laden an dem sie benötigt werden (eben virtuell).
Ist das nicht schon standardmäßig so?

Wenn mein VST 1.000.000 Nodes hat und aktuell wegen der kleinen Größe des Fensters nur 20 angezeigt werden, dann sollten doch eigentlich auch nur diese 20 initialisert werden. Oder nicht?


Edit
habe das gerade geprüft. Es werden alle auf einen schlag initialisiert. Egal ob aktuell sichtbar oder nicht.

jus 16. Apr 2019 15:01

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Sorry, dass ich den Beitrag wieder aufwärme, aber bin auf ein weiteres Problem gestossen. Also der Ansatz mit der der TObjectList zur Verwaltung der Nodedaten in den vorigen Beträgen, wenn diese keine weiteren Unterebenen besitzen, funktioniert sehr gut. Doch wie sieht es dann aus, wenn die Nodes unterebenen besitzen? :gruebel:

lg,
jus

Aviator 16. Apr 2019 15:28

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Dann gibt es in deiner
Delphi-Quellcode:
TObjectList<T>
eine zusätzliche Property die ebenfalls eine
Delphi-Quellcode:
TObjectList<T>
oder ein anderer ContainerType ist. Die ChildNodes verweisen dann auf einen Eintrag in dieser Liste. Wenn die Daten vom gleichen Typ sind (wie z.B. bei einer Verzeichnisstruktur), dann ist das recht einfach, da rekursiv. Bedenke, dass du dann im
Delphi-Quellcode:
Constructor
ein
Delphi-Quellcode:
Create
des ChildContainers und im
Delphi-Quellcode:
Destruktor
ein
Delphi-Quellcode:
Free
ausführen solltest.

jus 16. Apr 2019 17:29

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Zitat von Aviator (Beitrag 1430429)
Dann gibt es in deiner
Delphi-Quellcode:
TObjectList<T>
eine zusätzliche Property die ebenfalls eine
Delphi-Quellcode:
TObjectList<T>
oder ein anderer ContainerType ist. Die ChildNodes verweisen dann auf einen Eintrag in dieser Liste. Wenn die Daten vom gleichen Typ sind (wie z.B. bei einer Verzeichnisstruktur), dann ist das recht einfach, da rekursiv. Bedenke, dass du dann im
Delphi-Quellcode:
Constructor
ein
Delphi-Quellcode:
Create
des ChildContainers und im
Delphi-Quellcode:
Destruktor
ein
Delphi-Quellcode:
Free
ausführen solltest.

ok, das NodeObjekt um ein TObjectList zu erweitern sollte kein Problem darstellen. Doch wenn es nun Unterebenen gibt. Sollte eigentlich das Objekt, das die Nodedaten beinhaltet auch eine Referenz auf das überliegende Nodedaten-Objekt haben? Würdet ihr sowas machen reingeben?

Derzeit OHNE mehrere Unterebenen schaut es bei mir so aus:
Delphi-Quellcode:
unit Unit1;

interface

//....
type
  TNodeDataClass = class
  private
    FSpalte1: string;
    FSpalte2: string;
    FSpalte3: Integer;
  public
  property Spalte1: string read FSpalte1 write FSpalte1;
  property Spalte2: string read FSpalte2 write FSpalte2;
  property Spalte3: Integer read FSpalte3 write FSpalte3;
  end;

  TForm1 = class(TForm)
    vst: TVirtualStringTree;
    procedure FormCreate(Sender: TObject);
    procedure vstInitNode(Sender: TBaseVirtualTree; ParentNode,
      Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
    procedure vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
  private
    DataList: TObjectList; //<--- hier die NodeObjekte von TNodeDataClass
  end;

var
  Form1: TForm1;

implementation
Nach der Erweiterung von VST Nodes MIT mehreren Unterebenen:
Delphi-Quellcode:
unit Unit1;

interface

//....
type
  TNodeDataClass = class
  private
    FParentNode: TNodeDataClass;  // <------ eine Referenz auf oberen Knoten notwendig????????
    FSpalte1: string;
    FSpalte2: string;
    FSpalte3: Integer;
    FSubNodeDataList: TObjectList; // <- Für eventuelle Subnodes
  public
  property Spalte1: string read FSpalte1 write FSpalte1;
  property Spalte2: string read FSpalte2 write FSpalte2;
  property Spalte3: Integer read FSpalte3 write FSpalte3;
  end;

  TForm1 = class(TForm)
    vst: TVirtualStringTree;
    procedure FormCreate(Sender: TObject);
    procedure vstInitNode(Sender: TBaseVirtualTree; ParentNode,
      Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
    procedure vstGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
  private
    RootNodeDataList: TObjectList; //<--- hier die NodeObjekte von TNodeDataClass
  end;

var
  Form1: TForm1;

implementation

Aviator 16. Apr 2019 17:33

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Naja du könntest so etwas machen:

Delphi-Quellcode:
type
  TNodeDataClass = class
  private
    FParentNodeData: TNodeDataClass;
    FSpalte1: string;
    FSpalte2: string;
    FSpalte3: Integer;
  public
    constructor Create(AParent: TNodeDataClass); override;
    property Spalte1: string read FSpalte1 write FSpalte1;
    property Spalte2: string read FSpalte2 write FSpalte2;
    property Spalte3: Integer read FSpalte3 write FSpalte3;
  end;



implementation

constructor TNodeDataClass.Create(AParent: TNodeDataClass);
begin
  inherited Create;

  FParentNodeData := AParent;
end;

generic 2. Mai 2019 08:15

AW: Datenhaltung mit VirtualStringTree und Trennung der Businesslogik
 
Zitat:

Zitat von Codehunter (Beitrag 1429255)
Zitat:

Zitat von generic (Beitrag 1429220)
Wieso speichert Ihr den Objekt Zeiger nicht direkt im VST?
Dann braucht ihr die Zwischenklasse TTreeData nicht.

Ich vermute, das sind Altlasten. Lange Zeit ging das beim VST gar nicht anders.

Ich finde nicht, dass das Altlasten sind. Ich finde das ist brillant umgesetzt.
Wenn die Knotenanzahl fest steht, dann der VST direkt den gesamten benötigten Speichern mit einer Anfrage belegen. Durch die Ereignisse können dieser dann "on demand" befüllt werden.

Also von der Geschwindigkeit her - hervorragend.
Ich persönlich habe das aber nie genutzt, weil es die Software imho schwieriger macht.
Man muss ggf. seine DB-Komponente globaler haben und die so lange offen lassen bis alles geladen ist.
Callbacks sind eh nicht jedermanns Stärke.

Zitat:

Zitat von DieDolly (Beitrag 1429225)
AddChild benutzt man nicht. Das ist eine Todsünde, so wie ich das immer lese.
Wenn man AddChild benutzt, dann kann man auch gleich ein TListView benutzen mit Add().

Das habe ich noch nie gelesen.
AddChild hat nur den Nachteil, dass jeweils nur für ein Element der Speicher geholt wird.
Hast du mal ein Link für mich, wo ICH mich schlauer machen kann?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 Uhr.
Seite 4 von 5   « Erste     234 5      

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 by Thomas Breitkreuz