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 Komponenten-Entwicklung: xyz[i].name (https://www.delphipraxis.net/14892-komponenten-entwicklung-xyz%5Bi%5D-name.html)

lkz633 17. Jan 2004 14:54


Komponenten-Entwicklung: xyz[i].name
 
Hallo,

bin Anfänger in Komponentenentwicklung und würde jetzt gerne eine Struktur erzeugen, so dass ich darauf mit

Code:
componentname.xyz[i].name;
componentname.xyz[i].id
etc darauf zugreifen kann.

Wie mache ich das am besten, es klappt einfach nicht.

Im construktor möchte ich dies auch dann komplett füllen, was muss ich alles erzeugen? Wahrscheinlich eine abgeleiteten Typ von Stringlist für das xyz?

Danke und Gruss
lkz633

Skiron 17. Jan 2004 15:25

Re: Komponenten-Entwcilung: xyz[i].name
 
du kannst folgendes Machen:

Delphi-Quellcode:
type
  Typ1 = record
    Name: string;
    ID: string;
  end;

  MeineComp = class
    xyz: array of Typ1;
  end;

//im constructor:
begin
  setLength(xyz, 4); //Oder wie viel du halt drinnenhaben willst
  //Dann kannst du alles initialisieren...
end;

//außerhalb der komponente:
var
  h: MeineComp;

//irgendwo in einer prozedur
  h.xyz[1].Name := 'xxx';

Christian Seehase 17. Jan 2004 15:25

Re: Komponenten-Entwcilung: xyz[i].name
 
Moin lkz,

ist halt die Frage, ob xyz bei Dir wiederum ein Objekt, oder einfach nur ein Recordtyp sein soll.
In jedem Falle müsstest Du wohl ein (dynamisches) Array für xyz vorsehen

Beispiel:

Delphi-Quellcode:
type
  TMyRecord = packed record
    name : string;
    id  : integer;
  end;

  TMyComponent = class(TObject)
  private
    FMyList : array of TMyRecord;
      function Getxyz(index: integer): TMyRecord;
      procedure Setxyz(index: integer; const Value: TMyRecord);
  public
    constructor Create;
    procedure Add(const AsName : string;AiId : integer);
    property xyz[index : integer] : TMyRecord read Getxyz write Setxyz;
  end;

implementation

{$R *.DFM}

{ TMyComponent }

procedure TMyComponent.Add(const AsName: string; AiId: integer);
begin
  SetLength(FMyList,length(FMyList)+1);
  FMyList[high(FMyList)].name := AsName;
  FMyList[high(FMyList)].Id  := AiId;
end;

constructor TMyComponent.Create;
begin
  inherited;
  SetLength(FMyList,0);
end;

function TMyComponent.Getxyz(index: integer): TMyRecord;
begin
  Result := FMyList[index];
end;

procedure TMyComponent.Setxyz(index: integer; const Value: TMyRecord);
begin
  FMyList[index] := Value;
end;
Das Beispiel enthält keinerlei Sicherheitsprüfungen (Index), und das Array immer um einen Wert zu vergrössern, ist auch nicht besonders geschickt, aber es zeigt einen Weg auf, wie es grundsätzlich machbar wäre.

lkz633 17. Jan 2004 15:41

Re: Komponenten-Entwcilung: xyz[i].name
 
Hallo, das letzte soll auch ein record sein, habe es so mal hinbekommen(alles unwichtige weggelassen):

Code:
type tcontactitem = class
  private
    Fname: string;
    procedure Setname(const Value: string);
  public
  property name: string read Fname write Setname;
end;

type tContactItemList = class(TList)
  private
    function GetItems(Index: Integer): tcontactitem;
    procedure SetItems(Index: Integer; const Value: tcontactitem);
  public
    property Items[Index : Integer]: tcontactitem read GetItems write SetItems;
end;

type
  Toutextract = class(TComponent)
  private
    FOutlookVersion: outlookversion;
    Fcontacts: TContactItemList;
    procedure getcontacts;
    procedure Setcontacts(const Value: TContactItemList);
    { Private-Deklarationen }
  protected
    { Protected-Deklarationen }
  public
    constructor create(AOwner: TComponent); override;
    destructor destroy;
    property contacts: TContactItemList read Fcontacts write Setcontacts;
  end;
Jetzt greife ich aber darauf zu mit outextract1.contacts.Items[1].name, ich will aber direkt outextract1.contacts[1].name, wie bekomme ich das denn hin?

Herzlichen Dank
lkz633

lkz633 17. Jan 2004 16:07

Re: Komponenten-Entwcilung: xyz[i].name
 
Hab das jetzt mit
Code:
property contacts[Index : Integer]: TContactItem read Getcontacts write Setcontacts;
hinbekommen, das ich mit
Code:
contacts[1].name
darauf zugreifen kann, jedoch geht
Code:
contacts.name
auch. Warum?

Dadurch ist jetzt aber
Code:
tcontactlist=class(tlist)
rausgefallen, dies hätte ich aber gerne, so dass ich autom. auch Eigenschaften wie Index und Count habe.

Wie kann ich diese beiden Vorstellungen kombinieren?

Gruss lkz633

Jens Schumann 17. Jan 2004 16:25

Re: Komponenten-Entwcilung: xyz[i].name
 
Hallo,
das bekommst Du so hin (achte darauf das default hinter den Semikolon steht)
Delphi-Quellcode:
property Items[Index : Integer]: tcontactitem read GetItems write SetItems; default;
Den Vorschlag von lkz633 anstatt Records Objekte und anstatt dyn. Array's TList zu verwenden kann ich voll unterstützen.
Meine Grundsatz lautet: Verwende niemals Records. Es sei denn irgendein API verlangt einen Record als Parameter

An der Stelle habe ich mal meinen Senf zum Thema Speichern von Records abgegeben
http://www.delphipraxis.net/internal...399&highlight=

Dabei habe ich einen entscheidenden Vorteil vergessen zu erwähnen.
Wenn eine Datei als File of Record gespeichert wird und der Record wird mit der nächsten Version des Programms erweitert können die alten Dateien nicht mehr ohne weiteres gelesen werden. Wenn jedoch Objekte in Verbindung mit Write-/ReadComponent verwendet werden ist das kein Problem

lkz633 17. Jan 2004 16:31

Re: Komponenten-Entwcilung: xyz[i].name
 
:wall: :wall:

Ich hatte es schon so, nur das default ist mir noch nie über den Weg gelaufen..Naja wieder was gelernt :-)

Danke an alle die geholfen haben

Gruss lkz633

lkz633 17. Jan 2004 16:44

Re: Komponenten-Entwcilung: xyz[i].name
 
Kriegs irgendwie doch nicht gebacken......

Brauch ich tContactList noch oder nicht? Und wiso kann ich auch immer contacs.name benutzen?

Max

Jens Schumann 17. Jan 2004 16:47

Re: Komponenten-Entwcilung: xyz[i].name
 
Hallo,
es scheint so, also ob Du Deinen Source geändert hast.Poste doch mal den kompletten Source.

lkz633 17. Jan 2004 16:49

Re: Komponenten-Entwcilung: xyz[i].name
 
Den hab ich jetzt 5 mal hin und hergeändert....

Ich möchte halt 3 dinge erreichen:

- ich möchte mit contacts[1].name darauf zugreifen
- contacs.count sollte es auch geben
- contacs.name sollte aber nicht funktionieren

Geht das?

Max

Jens Schumann 17. Jan 2004 16:51

Re: Komponenten-Entwcilung: xyz[i].name
 
Hallo,
klar geht das. Da Du aber scheinbar Deinen Source nicht posten willst müsste ich jetzt
ein Beispiel selber machen. Also bitte zeige Deinen Source

lkz633 17. Jan 2004 16:54

Re: Komponenten-Entwcilung: xyz[i].name
 
Danke für deine Hilfe, hier mal der Source:

Code:
type tcontactitem = class
  private
    Fname: string;
    procedure Setname(const Value: string);
  public
    property name: string read Fname write Setname;
end;


type tContactItemList = class(TList)
  private
    function GetItems(Index: Integer): tcontactitem;
    procedure SetItems(Index: Integer; const Value: tcontactitem);
  public
    property Items[Index : Integer]: tcontactitem read GetItems write SetItems;default;
end;


type
  Toutextract = class(TComponent)
  private
    procedure SetOutlookVersion(const Value: outlookversion);
    function Getcontacts(Index: Integer): TContactItemlist;
    procedure Setcontacts(Index: Integer; const Value: TContactItemlist);
  protected
  public
    constructor create(AOwner: TComponent); override;
    destructor destroy;
    property contacts[Index : Integer]: TContactItemList read Getcontacts write Setcontacts;
  end;

Jens Schumann 17. Jan 2004 16:57

Re: Komponenten-Entwcilung: xyz[i].name
 
Hallo,
da scheint so einiges durcheinander zu sein. Ich bastel Dir mal ein Beispiel.
Bis gleich.

Jens Schumann 17. Jan 2004 17:10

Re: Komponenten-Entwcilung: xyz[i].name
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
studiere mal das Beispiel

lkz633 17. Jan 2004 17:44

Re: Komponenten-Entwcilung: xyz[i].name
 
Ich steh anscheinend grad auf dem Schlauch da ich es immer noch nicht hinbekomme:

Habe jetzt das hier:
Code:
type tcontactitem = class
  private
    Fname: string;
  public
    property name: string read Fname write Fname;
end;

type
  Toutextract = class(TComponent)
  private
    FList : TList;
    function Getcontacts(Index: Integer): TContactItem;
    function GetCount: Integer;
    procedure Setcontacts(Index: Integer; const Value: TContactItem);
  public
    constructor create(AOwner: TComponent); override;
    destructor destroy;override;
    property contacts[Index : Integer]: TContactItem read Getcontacts write Setcontacts; default;
    property Count : Integer read GetCount;
  end;
Also
Code:
Komponente.contacts[i].name
klappt jetzt, leider aber auch
Code:
Komponente.contacts.name
Warum?

Ausserdem sollte
Code:
komponente.contacts.count
funktionieren, es geht natürlich nicht sondern nur
Code:
komponente.count
aber wo soll ich denn sonst diese Deklaration hintun? Ich will ja auch nicht
Code:
contacts[1].count
Danke für deine Geduld und Mühe
lkz633

Jens Schumann 17. Jan 2004 17:55

Re: Komponenten-Entwcilung: xyz[i].name
 
Zitat:

Zitat von lkz633
Ausserdem sollte
Code:
komponente.contacts.count
funktionieren, es geht natürlich nicht

Das kann auch nicht funktionieren, da contacts vom Type Tcontactitem ist und Tcontactitem keine
Count property hat.

Zitat:

Zitat von lkz633
Code:
Komponente.contacts.name

Warum das klappt ist mir schleierhaft.

Wenn Du Deinen Code komplett (also mit Methoden usw) posten würdest schau ich mir das noch einmal an.

lkz633 17. Jan 2004 17:58

Re: Komponenten-Entwcilung: xyz[i].name
 
Zitat:

Zitat von Jens Schumann
Zitat:

Zitat von lkz633
Ausserdem sollte
Code:
komponente.contacts.count
funktionieren, es geht natürlich nicht

Das kann auch nicht funktionieren, da contacts vom Type Tcontactitem ist und Tcontactitem keine
Count property hat.

Genau dies will ich aber ja erreichen, deswegen meine ganzen Umwege mit einer zusätzlichen TContactList, da diese dann eine Count Eigenschaft hätte.

Ich würde also gerne sowohl

Code:
Komponnete.contacts[i].name;
als auch
Code:
Komponente.contacts.count
erreichen.

Geht dies dann gar nicht?

Gruss lkz633

Jens Schumann 17. Jan 2004 18:07

Re: Komponenten-Entwicklung: xyz[i].name
 
Hallo,
da Du keine Source rausrückst muss ich jetzt mit meinen Beispiel kommen

Delphi-Quellcode:
  TMyListItems = class;

  TMyListItem = class(TObject)
  private
    function GetCount: Integer;
  private
    FName: String;
    FMyListItems : TMyListItems;
  public
    constructor Create(MyListItems : TMyListItems);
    property Count : Integer read GetCount;
    property Name : String read FName write FName;
  end;

...

function TMyListItems.Add(const aName : String): TMyListItem;
begin
  Result:=TMyListItem.Create(Self);
  Result.Name:=aName;
  FList.Add(Result);
end;

...

function TMyListItem.GetCount: Integer;
begin
  If Assigned(FMyListItems) then
    Result:=FMyListItems.Count
    else
      Result:=-1; // Zeigt dass das TMyListItem in keiner Liste hängt
end;
Der Trick ist , in jedem TMyListItem sich den entsprechenden TMyListItems zu merken.

lkz633 17. Jan 2004 18:13

Re: Komponenten-Entwicklung: xyz[i].name
 
Aber dann kann ich doch immer noch nicht contacts.count machen oder?

Hier mein Code(mehr hab ich seit 3 Stunden nicht zustandegebracht :wall: )

Code:
type tcontactitem = class
  private
    Fname: string;
  public
    property name: string read Fname write Fname;
end;


type
  Toutextract = class(TComponent)
  private
    FList : TList;
    function Getcontacts(Index: Integer): TContactItem;
    function GetCount: Integer;
    procedure Setcontacts(Index: Integer; const Value: TContactItem);
  public
    constructor create(AOwner: TComponent); override;
    destructor destroy;override;
    property contacts[Index : Integer]: TContactItem read Getcontacts write Setcontacts; default;
    property Count : Integer read GetCount;
   end;

Jens Schumann 17. Jan 2004 18:16

Re: Komponenten-Entwicklung: xyz[i].name
 
Hallo,
Du hast mich immer noch nicht verstanden. Ich möchte die komplette unit !!!
Auch den Code für die Methoden !!! D.h. ich möchte z.B. sehen wie Du den Setter Setcontacts realisiert hast. Damit das ganze mal richtig testen kann.

lkz633 17. Jan 2004 18:19

Re: Komponenten-Entwicklung: xyz[i].name
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das Problem ist das ich nicht mehr habe. Ich wollte halt erstmal das der Zugriff klappt bevor ich die Methoden angehe.

Aber hier die komplette Unit.

lkz633

Jens Schumann 17. Jan 2004 18:39

Re: Komponenten-Entwicklung: xyz[i].name
 
Hallo,
ich habe mal ein bißchen an Deinem Source herumgefummelt.
Das einzige was ich Dir bieten kann ist
Code:
komponente.contacts[x].count
Code:
komponente.contacts.count
Wäre auch sinnlos. Contacts ist nur eine Array Property. D.h. in Wirklichtkeit stecken die in FList verwalteten Objekte dahinter. Welches dieser Objekte möchtest Du denn mit komponente.contacts.count ansprechen ??? Wozu brauchst Du das überhaupt ? komponente.count liefert doch schon das Ergebnis.

Hier jetzt der Source
Delphi-Quellcode:
unit outextract;

interface

uses
  windows,SysUtils, Classes, Controls,comobj,variants;

type
  outlookversion = (ovOutlook,ovOutlookExpress);


Toutextract = class;

 tcontactitem = class
  private
    Fname      : string;
    Foutextract : Toutextract;
    function GetCount: Integer;
  public
    constructor Create(outextract : Toutextract);
    property name : string read Fname write Fname;
    property Count : Integer read GetCount; // damit geht contacts[x].Count
end;



  Toutextract = class(TComponent)
  private
    FList : TList;
    FOutlookVersion: outlookversion;
    function GetCount: Integer;
    function GetItem(Index: Integer): TContactItem;
    procedure SetOutlookVersion(const Value: outlookversion);
  public
    constructor create(AOwner: TComponent); override;
    destructor destroy;override;
    function Add(const aName : String) : tcontactitem;
    procedure Clear;
    property contacts[Index : Integer]: TContactItem read GetItem; default;
    property Count : Integer read GetCount;
  published
    property OutlookVersion:outlookversion read FOutlookVersion write SetOutlookVersion;

  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('SEPT-Solutions', [Toutextract]);
end;






{ Toutextract }

function Toutextract.Add(const aName: String): tcontactitem;
begin
  Result:=tcontactitem.Create(Self);
  Result.name:=aName;
  FList.Add(Result);
end;

procedure Toutextract.Clear;
var
  iCnt : Integer;
begin
  For iCnt:=0 to FList.Count-1 do
    TObject(FList[iCnt]).Free;
  FList.Clear;
end;

constructor Toutextract.create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FList:=TList.Create;
end;

destructor Toutextract.destroy;
begin
  FList.Free;
  inherited Destroy;
end;

function Toutextract.GetCount: Integer;
begin
  Result:=FList.Count;
end;

function Toutextract.GetItem(Index: Integer): TContactItem;
begin
  Result:=TContactItem(FList[Index]);
end;

procedure Toutextract.SetOutlookVersion(const Value: outlookversion);
begin
  FOutlookVersion:=Value;
end;

{ tcontactitem }


{ tcontactitem }

constructor tcontactitem.Create(outextract: Toutextract);
begin
  inherited Create;
  Foutextract:=outextract;
end;

function tcontactitem.GetCount: Integer;
begin
  If Assigned(Foutextract) then
    Result:=Foutextract.Count
    else
      Result:=-1; // Zeigt dass das TMyListItem in keiner Liste hängt
end;

end.

lkz633 17. Jan 2004 18:52

Re: Komponenten-Entwicklung: xyz[i].name
 
Ich hatte mir halt irgendwie gedacht das es sehr viel logischer ist, ich will ja die Anzahl der Kontakte und nicht die Anzahl der Komponenten. Bei delphi Komponenten geht es doch auch so, z.B listbox.items.count und listbox.item[i]

Naja, ist ja nicht so schlimm.

Herzlichen Dank für deine Hilfe!!!!

Gruss lkz633

lkz633 17. Jan 2004 18:53

Re: Komponenten-Entwicklung: xyz[i].name
 
hm... contacts.name, contacts.count usw geht immer noch, wiso?

Hat da jemand eine Erklärung für?

Gruss lkz633

Jens Schumann 17. Jan 2004 18:55

Re: Komponenten-Entwicklung: xyz[i].name
 
Hallo,
das wird Dir nur von Delphi angeboten. Versuch es mal zu compilieren.

lkz633 17. Jan 2004 19:00

Re: Komponenten-Entwicklung: xyz[i].name
 
:oops:

Dann werde ich mal weiter mein Glück versuchen...puh Komponenten sind gar nicht so leicht

Jens Schumann 17. Jan 2004 19:02

Re: Komponenten-Entwicklung: xyz[i].name
 
Hallo,
jetzt habe ich geschnallt was Du möchtest. Mein erstes Beispiel enthält die Lösung.
Du musst ein Objekt dazwischenschalten. Dieses Objekt verwaltet dann die einzelnen Objekte.
Bei TListBox ist die property Items vom Type TStrings. In meinen ersten Beispiel ist es TMyListItems

Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  iCnt : Integer;
begin
  For iCnt:=0 to FMyListItems.Count-1 do // Zugriff auf Count
    ListBox1.Items.Add(FMyListItems[iCnt].Name); // Zugriff auf die Objekte
end;

lkz633 17. Jan 2004 19:08

Re: Komponenten-Entwicklung: xyz[i].name
 
Sorry jetzt bin ich ganz verwirrt......

Hab grad gemerkt das contacts.add dann ja auch nicht geht......

Könntest du wenn du verstanden hast was ich mein nochmals die Unit von grade abgeändert posten, das wäre sehr nett....


lkz633

Jens Schumann 17. Jan 2004 19:10

Re: Komponenten-Entwicklung: xyz[i].name
 
Hallo,
leider nicht. Da ich jetzt mit unseren Kindern Die Siedler spielen werde.

SCHAU IN MEIN ERSTES BEISPIEL DA STEHT ALLES DRIN

lkz633 17. Jan 2004 19:57

Re: Komponenten-Entwicklung: xyz[i].name
 
Jepeeeeee :-D Jetzt kann ich alles genau so machen wie ich es wollte...danke danke danke


Ich wollte immer soetwas machen
Code:
    property contacts[X : Integer] : Tcontact read GetItems;
  end;
anstatt so etwas:

Code:
  property Items[X : Integer] : Tcontact read GetItems;[b]default[/b];

  public
    [b]Contacts: Tcontactlist;[/b]
Gruss lkz633


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