Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Speichern eines Objekts mit einer Liste von Objekten im DFM (https://www.delphipraxis.net/150299-speichern-eines-objekts-mit-einer-liste-von-objekten-im-dfm.html)

RSE 13. Apr 2010 08:12


Speichern eines Objekts mit einer Liste von Objekten im DFM
 
Hallo!

Ich entwickle gerade eine neue Komponente und beschäftige mich nun erstmals mit Property Editoren, Component Editoren, der Speicherung von eigenen Objekten im DFM etc.

Hintergrundinfos:
Meine Komponente (TMyComp) hat eine Items-Property, in der ein Objekt (TMyItemList) gespeichert ist, welches eine Liste von eigenen Objekten (TMyItem) in einem dynamischen Array verwaltet. Die Eigenschaft TMyComp.Items soll im Objektinspektor angezeigt werden, um an den Component Editor ranzukommen, weiter nichts (Realisierung ist bereits geglückt). In diesem Component Editor wird TMyItemList mit TMyItems gefüllt, ähnlich wie bei einer ActionList. Später möchte ich die TMyItem-Objekte auch im Objektinspektor anzeigen können, wenn sie in meinem Component Editor ausgewählt sind.

Fragen:
Wie muss ich TMyComp.Items, welches vom Typ TMyItemList ist, im DFM speichern? Wie muss ich die TMyItem-Objekte in TMyItemList speichern, damit ich sie später im OI anzeigen lassen kann? Ich habe schon DefineProperties (Eigene Property - Zur Runtime wieder zurückgesetzt) gefunden und mir die Hilfe dazu durchgelesen, bin mir allerdings noch etwas unsicher, ob das die richtige Lösung für mich ist und wie ich das anwenden muss (in TMyComp für Items und in TMyItemList für das Array-Property mit den TMyItem-Objekten?).

Delphi-Quellcode:
TMyItem = class // könnte man auch z.B. von TComponent ableiten, wenn notwendig
  ...
end;

TMyItemList = class // könnte man auch z.B. von TComponent ableiten, wenn notwendig
  private
    FItems: array of TMyItem;
  protected
    function GetItem(Index: Integer): TChoiceGroupItem;
    ...
  public
    procedure Clear;
    function Count: Integer;
    procedure Delete(AIndex: Integer);
    ...
    property Item[Index: Integer]: TMyItem read GetItem; default;
end;

TCustomMyComp = class(TCustomControl)
  private
    FItems: TMyItemList;
    ...
  public
    ...
    property Items: TMyItemList read FItems;
end;
Umgebung: Delphi 5 auf WinXP

uligerhardt 13. Apr 2010 08:48

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
WIMRE sind für das Streaming von Listen Delphi-Referenz durchsuchenTCollection und Delphi-Referenz durchsuchenTCollectionItem gedacht.

RSE 13. Apr 2010 09:30

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Danke für den Hinweis, ich werd mir die Klassen mal ansehen.

RSE 13. Apr 2010 11:09

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Jetzt weiß ich wieder, was mich an diesen vorgefertigten Listen immer stört: Wenn ich mir ein Item zurückgeben lasse, dann ist das vom Typ TCollectionItem und nicht von meinem Typ TMyItem. Dadurch muss ich immer erst einen Typecast durchführen, bevor ich auf meine Eigenschaften zugreifen kann. :x
Delphi-Quellcode:
MyItemList.ItemClass(MyItemList.Items[2]).MyProperty := 'was'; // mit TCollection
MyItemList[2].MyProperty := 'was';                            // eigene Lösung mit Items als default Property
Dem Nutzer meiner Komponente kann ich das wohl kaum abverlangen. Das heißt ich müsste die Collection komplett kapseln. Ist das wirklich so gedacht? :gruebel:

Wenn ich meine von TCollection und TCollectionItem abgeleiteten Klassen so vergewaltige, dass der Rückgabetyp TMyItem statt TCollection ist (Konstruktor, Add, Items etc. mit neuen Versionen verdecken und diverse Aufrufe umbauen), dann wird wohl der mitgelieferte Editor auch nicht mehr funktionieren. Vielleicht ergeben sich sogar noch mehr und unlösbare Fehler daraus...

Mein Fazit: Der Weg über TCollection ist Mist.

Also: Überzeugt mich vom Gegenteil oder beantwortet meine ursprüngliche Frage. :wink:

himitsu 13. Apr 2010 11:23

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Zitat:

Zitat von RSE
Jetzt weiß ich wieder, was mich an diesen vorgefertigten Listen immer stört: Wenn ich mir ein Item zurückgeben lasse, dann ist das vom Typ TCollectionItem und nicht von meinem Typ TMyItem. Dadurch muss ich immer erst einen Typecast durchführen, bevor ich auf meine Eigenschaften zugreifen kann. :x

Aber dafür kommt die Treamingkomponente mit deinen Items und Itemlisten klar und du bekommt recht einfach deine Objekte in die DFM rein :zwinker:

Klar geht es auch irgendwie ohne, aber dann muß sich deine "Mutterkomponente" selber um das (De)Serialisieren der Listen und Komponenten kümmern.

TTreeView macht das z.B.
und der Dank ist, daß die selbstgestreamten Daten sich seit Delphi 2009 geändert haben und eine in Delphi 7 gefüllte (im Formeditor) TreeView in D2010 urplötzlich kompett lehr ist, weil die TreeView die alten Daten nicht mehr erkennt. :stupid:

uligerhardt 13. Apr 2010 11:24

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Zitat:

Zitat von RSE
Jetzt weiß ich wieder, was mich an diesen vorgefertigten Listen immer stört: Wenn ich mir ein Item zurückgeben lasse, dann ist das vom Typ TCollectionItem und nicht von meinem Typ TMyItem. Dadurch muss ich immer erst einen Typecast durchführen, bevor ich auf meine Eigenschaften zugreifen kann. :x
Delphi-Quellcode:
MyItemList.ItemClass(MyItemList.Items[2]).MyProperty := 'was'; // mit TCollection
MyItemList[2].MyProperty := 'was';                            // eigene Lösung mit Items als default Property
Dem Nutzer meiner Komponente kann ich das wohl kaum abverlangen. Das heißt ich müsste die Collection komplett kapseln. Ist das wirklich so gedacht? :gruebel:

Klar ist das so gedacht. Schau dir halt mal an, wo die VCL TCollection verwendet (z.B. TStatusPanels) - das ist schon machbar. :-)

Zitat:

Zitat von RSE
Wenn ich meine von TCollection und TCollectionItem abgeleiteten Klassen so vergewaltige, dass der Rückgabetyp TMyItem statt TCollection ist (Konstruktor, Add, Items etc. mit neuen Versionen verdecken und diverse Aufrufe umbauen), dann wird wohl der mitgelieferte Editor auch nicht mehr funktionieren. Vielleicht ergeben sich sogar noch mehr und unlösbare Fehler daraus...

Mein Fazit: Der Weg über TCollection ist Mist.

Also: Überzeugt mich vom Gegenteil oder beantwortet meine ursprüngliche Frage. :wink:

Ich werd jetzt nicht ewig versuchen, dich zu deinem Glück zu zwingen. :mrgreen: Aber wenn ich Komponenten für Delphi schreibe, würde ich auch den Delphi-Weg dabei gehen. Wie gesagt - in den VCL-Sourcen gibt's genug Beispiele.

RSE 13. Apr 2010 11:36

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Ich danke für die Antworten. Das mit der Kapselung ist mir erst kurz vor dem Absenden des Beitrags eingefallen und dann hab ich´s noch mit reingeschrieben. Je mehr ich jetzt in der Mittagspause drüber nachgedacht habe, desto besser gefällt mir die Variante. Also werde ich die Collection komplett kapseln. ;-)

Danke an alle Helfer!

RSE 13. Apr 2010 15:15

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Ich hab mir jetzt VCL-Quelltext angesehen, meine Items so angepasst, dass sie mit dem Property Editor von TCollectionItem erstellt werden können (Konstruktor ohne weitere Parameter etc.) und die Items-Property auf Published gesetzt. Trotzdem sind die erstellten Items weg, wenn ich die Form neu lade.

Was muss ich tun, damit TCollection nun meine Items auch speichert?

Ich nehme mal an, dass mir noch ein Standardkniff fehlt, falls ihr weitere Infos oder Quelltext braucht, bitte fragen.

RSE 16. Apr 2010 13:00

Re: Speichern eines Objekts mit einer Liste von Objekten im
 
Da hier keiner mehr antwortet und sich das Thema ja nun auch etwas gewandelt hat, habe ich einen neuen Thread erstellt, in dem nun die Benutzung von TCollection diskutiert werden darf: TCollection speichert nicht im DFM, was fehlt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:50 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