Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Generics (Objectlist) in Komponenten (https://www.delphipraxis.net/169087-generics-objectlist-komponenten.html)

Keldorn 27. Jun 2012 21:10

Delphi-Version: XE2

Generics (Objectlist) in Komponenten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo
Ich scheitere mal wieder an den generics:?. Wie kann ich eine beliebige generische Objectliste an eine Komponente übergeben und innerhalb einer Komponente verwenden?

z.B. für eine Einstellungskomponente wie im Anhang, die ich gern mit einer generics.objectlist untersetzen möchte. Im Panel rechts soll man weitere Komponenten platzieren können, wo die eigentlichen Einstellungen für jedes einzelne Objekt vornehmen kann. Die ganze Logik mit neu/löschen etc soll die Kompo übernehmen und nur 2 Ereignisse für das Lesen und Setzen eines einzelnen Objektes bereitstellen.

Das wäre alles nicht das Thema, aber ich weiß eben nicht, wie ich die generics.objetlist mit unbekannten Typ hinterlege…
hat jemand einen kleinen Tipp für mich,
Danke im Voraus Frank

himitsu 27. Jun 2012 21:20

AW: Generics (Objectlist) in Komponenten
 
Du erstellst dir einen Typen für diese Liste.

Delphi-Quellcode:
type
  TDeineListe = TObjectList<TDeinObjekt>;
Und verwendest diesen Typen, genauso, wie du auch die nichtgenerische TObjectList verwenden würdest.


Aber:
Wenn du diesen Typen für ein Published-Property verwenden willst, dann gibt es ein klitzekleines Problem, denn im "internen" Klassennamen der TDeineListe gibt es < und >,
da TDeineListe nur ein Alias ist ist, wärend der eigentliche Typ "TObjectList<TDeinObjekt>" lautet und genau diese Zeichen sind in der VCL nicht für Typtbezeichner erlaubt.

Lösung: Ein "nichtgerneischer" Typ, also in der letzen Ableitung.

Delphi-Quellcode:
type
  TDeineGenListe = TObjectList<TDeinObjekt>;

  TDeineListe = class(TDeineGenListe)
    // wenn hier nix ist, dann geht auch das Nächste.
  end;

  TDeineListe = class(TDeineGenListe);

// oder ohne den unnützen Zwischentypen/Alias

type
  TDeineListe = class(TObjectList<TDeinObjekt>);


Weitere Typen kannst du natürlich nur über Vererbung bereitstellen, da du deiner "VCL"-Komponente natürlich nur einen Typen bekanntmachen kannst.
(abgesehn, wenn man es auf mehere Zugangspunkte, also Methoden und/oder Property verteilt)

Also entweder für die Übergabepunkte TObject (nicht "List") nutzen, was der Vorfahre aller Delphiklassen ist.
Oder eben ein generischer Typ (wie oben genannt) als Vorfahre und für die Schnittstellen dann davon weitere Typen ableiten.

sx2008 28. Jun 2012 02:44

AW: Generics (Objectlist) in Komponenten
 
Du könntest aber auch das Wort "Generics" mal temporär komplett aus deinem Gedächtnis streichen.
Denn die VCL bietet seit Delphi 2 einen Weg Objekte innerhalb TStrings zu speichern.
Eine Listbox hat ja das Property Items.
Man kann nun für jeden Eintrag in Items ein zusätzliches Object speichern.
Delphi-Quellcode:
var
  p : TMobilphone;
begin
  p := TMobilphone.Create;
  p.Name := 'S3';
  p.Preis := 599.0;
  listbox1.Items.AddObject('Samsung S3', p);

  p := TMobilphone.Create;
  p.Name := '4S';
  p.Preis := 599.0;
  listbox1.Items.AddObject('IPhone 4S', p);
Diese Objekte kann man natürlich auch wieder auslesen; is klar.
Damit kannst du TListBox, TComboBox, TMemo unverändert verwenden und zusätzlich Objekte speichern.

http://delphi.about.com/od/vclusing/..._addobject.htm
http://delphi.about.com/od/delphitip...gs-objects.htm

jaenicke 28. Jun 2012 06:32

AW: Generics (Objectlist) in Komponenten
 
Das Casten ist da dank Generics nach außen gar nicht mehr notwendig. Ich habe dafür einfach eine generische TStringObjectList geschrieben, die den alten Code 1:1 ersetzt, aber dabei dank Generics typsicher ist.

Auf die Typsicherheit ganz zu verzichten macht aber nur dann Sinn, wenn es sich damit nicht machen lässt. Und da bin ich mir hier nicht ganz sicher wie das gemeint ist.
Zitat:

Zitat von Keldorn (Beitrag 1172734)
Ich scheitere mal wieder an den generics:?. Wie kann ich eine beliebige generische Objectliste an eine Komponente übergeben und innerhalb einer Komponente verwenden?

Wenn du damit meinst, dass du ein Objekt hast, an das du parallel wahlweise verschiedene generische Objektlisten übergeben willst, geht das nicht, da ein gemeinsamer Vorfahr fehlt.

Eine Möglichkeit wäre die Klasse so zu definieren:
Delphi-Quellcode:
type
  TMySettings<T> = class
  public
    property MyList: TObjectList<T>
  end;
Dann kann der Benutzer sich selbst die passende erzeugen und verwenden.

Wenn es aber ein und dieselbe Komponente sein soll, die man auf ein Formular legen soll, dann geht das so nicht. Dann bliebe wirklich nur ohne Generics zu arbeiten oder als Typ in der Liste TValue (Unit RTTI) zu nehmen. Das ist ein Typ, der ähnlich wie Variants funktioniert, aber keine Typumwandlungen macht. Wenn ich einen Integer reinlege, kann ich keinen String herausholen. Ich kann aber auch einen String hineinpacken.

Keldorn 30. Jun 2012 09:25

AW: Generics (Objectlist) in Komponenten
 
Hallo,

danke für eure Antworten:)

kurz noch mal zum besseren Verständnis: ich habe z.B. meine Einstellungsklasse, mit diversen Objectlisten für diverse Einstellungen (TBasisObjectList<Tobject1>, TBasisObjectList<Tobject2>, TBasisObjectList<Tobject3>, …) und will dann in meiner Einstellungsform dann für jede Objectlist eine solche Kompo verwenden.

sx2008: ja, die Vorgehensweise kenne ich. Aber das macht die Sache für mich nicht einfacher, ich will ja die ganze Logik in der Komponente haben. Das würde so dann nicht funktionieren, wenn ich die Objekte mit dranhänge oder dann später die Objektliste wieder aufbaue.

Zitat:

Zitat von jaenicke (Beitrag 1172758)

Eine Möglichkeit wäre die Klasse so zu definieren:
Delphi-Quellcode:
type
  TMySettings<T> = class
  public
    property MyList: TObjectList<T>
  end;

Genau, aber was ich ja bräuchte wäre das als Komponente
Delphi-Quellcode:
  TFrameXYZ<T> = class(TFrame)
Geht so leider nicht.

Ich muß noch mal drüber schlafen, werde es wahrscheinlich so machen, dass ich mir die listen in der Art übergebe
Delphi-Quellcode:
procedure Proc_ObjectListeDatenSetzen<T: class>(AList: TObjectList<T>);
Und die Daten dann dort auslese und in eine normale ObjectList übertrage. Ich hatte halt gehofft, ich kann direkt mit der übergebenen Liste weiterarbeiten, das würde vieles vereinfachen.

Gruß Frank

jaenicke 30. Jun 2012 10:08

AW: Generics (Objectlist) in Komponenten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Keldorn (Beitrag 1173027)
Genau, aber was ich ja bräuchte wäre das als Komponente
Delphi-Quellcode:
  TFrameXYZ<T> = class(TFrame)
Geht so leider nicht.

Nicht direkt, nein, aber indirekt mit einem nicht ganz schönen Trick schon, siehe Anhang.

Ob das Sinn macht, ist eine andere Frage. Denn irgendwo muss man den Typ ja schon explizit behandeln für solche Komponenten. :gruebel:

himitsu 30. Jun 2012 11:06

AW: Generics (Objectlist) in Komponenten
 
Delphi hat leider ein sehr großes Problem, bei der Framevererbung, speziell der FormDesigner kommt damit oftmals einfach nicht klar
und wenn er was nicht versteht, dann sagt er sich einfach (ohne uns ein Wort zu sagen, was ihm nicht gefällt) "das ist eine TForm" und fertig.
Bei TForm-Nachfahren fällt dieses Problem natürlich nicht auf.

Das merkt man ganz schnell, wenn der Frame urplötzlich einen Border und Titelleiste bekommt.
Wenn man das dann speichert, kann man dieses Frame nurgends mehr verwenden, denn wenn im Programm dann der DFM-Loader dieses Frame laden soll, dann kracht es gewaltig, sobald Property der TForms auftauchen, wie z.B. ClientHeight, welche es im TFrame nicht gibt.



De Trick mit dem "TFrame" als Zwischentyp hilft zwar das Frame als Frame im Formdesigner zu laden, aber wenn/da der Formdesigner dieses nicht richtig läd, sieht man natürlich das Edit nicht im Formdesigner, bzw. eben auch nicht alle anderen Komponenten, welche man auf den Vorfahren legen würde.


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