Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Array als Published Property (https://www.delphipraxis.net/47529-array-als-published-property.html)

Taladan 12. Jun 2005 16:02


Array als Published Property
 
Hallo. Ich möchte gern ein Array als published property erstellen. Laut OH geht dies, jedoch nur, wenn man ein Komponenteneditor erstellt. Das wäre ja alles kein Problem, jedoch funktionieren die funktionen nicht so wie ich will, nämlich gar nicht. Ich kann nicht über
Database1.Liste(0).id auf den Record zu greifen. Kann mir einer sagen warum?

Delphi-Quellcode:
type
    TFeldRecord = record
          ID : Integer;
          Name : String;
          Typ : Integer;
end;

type
   TFeldListe = class(TPersistent)
    private
      FListe: array of TFeldRecord;
      procedure SetField(Index: Integer; Value: TFeldRecord);
      function GetField(Index: Integer): TFeldRecord;
    public
       property Liste[Index: Integer]: TFeldRecord read GetField write SetField;
    end;

type
  TDataBase = class(TComponent)
  private
    { Private-Deklarationen }
    FPfad : string;
    FDatei : String;
    FListe : TFeldListe;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }   // Zur Laufzeit
    constructor Create (AOwner: TComponent); override;
  published
    { Published-Deklarationen }          // Zur Designzeit
    property Pfad : String Read FPfad Write FPfad;
    property Datei : String Read FDatei Write FDatei;
    property Liste : TFeldliste read fListe write fliste;
  end;

SirThornberry 12. Jun 2005 16:13

Re: Array als Published Property
 
was für ein Fehler kommt? estellst du überhaupt die Instanz von TFeldliste (fListe)?
und wo setzt du überhaupt die Länge (SetLength) von "FListe" in TFeldListe?

marabu 12. Jun 2005 16:14

Re: Array als Published Property
 
Hallo taladan,

Zitat:

Zitat von taladan
Ich kann nicht über Database1.Liste(0).id auf den Record zu greifen. Kann mir einer sagen warum?

du hast deine Klassen so entworfen, dass du nur mit Database1.Liste.Liste[0].ID zugreifen kannst. Außerdem fehlt eventuell ein Konstruktor in der Klasse TFeldListe.

Grüße vom marabu

Taladan 12. Jun 2005 16:28

Re: Array als Published Property
 
Also. Hier meine Komponentenunit:
Delphi-Quellcode:
unit DataBaseControls;

interface

uses
  Classes, Controls, Forms, Graphics, StdCtrls, Dialogs;

type
    TFeldRecord = record
          ID : Integer;
          Name : String;
          Typ : Integer;
end;

type
   TFeldListe = class
    private
      FListe: array of TFeldRecord;
      procedure SetField(Index: Integer; Value: TFeldRecord);
      function GetField(Index: Integer): TFeldRecord;
    public
       property Feld[Index: Integer]: TFeldRecord read GetField write SetField;
    end;

type
  TDataBase = class(TComponent)
  private
    { Private-Deklarationen }
    FPfad : string;
    FDatei : String;
    FListe : TFeldListe;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }   // Zur Laufzeit
    constructor Create (AOwner: TComponent); override;
  published
    { Published-Deklarationen }          // Zur Designzeit
    property Pfad : String Read FPfad Write FPfad;
    property Datei : String Read FDatei Write FDatei;
    property Liste : TFeldliste read fListe write fliste;
  end;

implementation

// TDatabase

constructor TDataBase.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  FListe := TFeldliste.Create;
end;

//TFeldliste

procedure TFeldliste.SetField(Index: Integer; Value: TFeldRecord);
var l : Integer;
begin
    L := Length(FListe);
    if (L >= Index) then
    begin
         Index := Index - 1;
         FListe[Index].ID := (Index+1);
         FListe[Index].Name := value.Name;
         FListe[Index].typ := value.Typ;
    end
    else
    begin
         L := (length(FListe) + 1);

         SetLength(FListe, L);

         FListe[High(FListe)].ID := Index;
         FListe[Index].Name := value.Name;
         FListe[Index].typ := value.Typ;
    end;

end;

function TFeldliste.GetField(Index: Integer): TFeldRecord;
begin
  result := Fliste[index];
end;



end.
und hier mein Editor:

Delphi-Quellcode:
unit FeldEditor;

interface

uses
  Windows, Classes, Graphics, Forms, Controls, Buttons, DesignIntf,
  DesignWindows, StdCtrls, ComCtrls, DesignEditors, DataBaseControls, SysUtils;


type
  TFeldEditorDlg = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button3Click(Sender: TObject);
  private
    FFelder : TFeldListe;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure FormCreate(Sender: TObject);
    property EditorFelder : TFeldListe read FFelder write FFelder;
  end;

  TFeldProperty = class(TClassProperty)
  public
    procedure Edit; override;
    function GetAttributes: TPropertyAttributes; override;
  end;

  TFeldEditor = class(TDefaultEditor)
  protected
    procedure EditProperty(const PropertyEditor: IProperty;
      var Continue: Boolean); override;
  public
    procedure ExecuteVerb(Index: Integer); override;
    function GetVerb(Index: Integer): string; override;
    function GetVerbCount: Integer; override;
  end;

procedure Register;

implementation
{$R *.dfm}


  { TFeldProperty }

procedure TFeldProperty.Edit;
var
  Felder: TFeldListe;
  FeldEditor: TFeldEditorDlg;
begin
  Felder := TFeldListe(GetOrdValue);
  FeldEditor := TFeldEditorDlg.Create(Application);
  try
    FeldEditor.FFelder := Felder;
    FeldEditor.ShowModal;
  finally
    FeldEditor.Free;
  end;
end;

function TFeldProperty.GetAttributes: TPropertyAttributes;
begin
  Result := [paDialog, paSubProperties];
end;


  { TFeldEditor - Verbindungen/Objektinspektor }

procedure TFeldEditor.EditProperty(const PropertyEditor: IProperty;
  var Continue: Boolean);
var
  PropName: string;
begin
  PropName := PropertyEditor.GetName;
  if (CompareText(PropName, 'Felder') = 0) then
  begin
    PropertyEditor.Edit;
    Continue := False;
  end;
end;

function TFeldEditor.GetVerb(Index: Integer): string;
begin
  if Index = 0 then
    Result := 'Felder'
  else Result := '';
end;


function TFeldEditor.GetVerbCount: Integer;
begin
  Result := 1;
end;


procedure TFeldEditor.ExecuteVerb(Index: Integer);
begin
  if Index = 0 then Edit;
end;

  { Sonnstige }


procedure Register;
begin
  RegisterComponents('DataBaseControls', [TDataBase]);
  RegisterComponentEditor(TDataBase, TFeldEditor);
  RegisterPropertyEditor(TypeInfo(TFeldliste), nil, '', TFeldProperty);
end;

  { TFeldEditorDlg - Formular }

procedure TFeldEditorDlg.FormCreate(Sender: TObject);
begin
  FFelder := TFeldListe.Create;
end;


procedure TFeldEditorDlg.Button3Click(Sender: TObject);
begin
  ffelder.Feld[0].id := 0;
end;

end.
Ziel soll es sein. Ein Array zu haben, welches folgendermaßen zugegriffen wird.

DataBase1.Liste[0].ID oder DataBase1.Liste.Feld[0].id

Irgendwie muß so was ja gehen, da eine Stringlist ja auch nix anderes ist, als ein Array von Strings.

Taladan 12. Jun 2005 16:37

Re: Array als Published Property
 
Wenn ich z.b. so zu greifen will, steht da immer, das der linken Seite nichts zu gewiesen werden kann

ffelder.Feld[0].id := 0;

Natürlich will ich später auch auf die einzelnen Array-Elemente zu greifen können.

SirThornberry 12. Jun 2005 17:16

Re: Array als Published Property
 
das liegt daran das das property den gesamten record zurück gibt. Es müsste also wenn dan so heißen
Delphi-Quellcode:
var LRecord: TFeldRecord;
begin
  LRecord := ffelder.Feld[0];
  LRecord.id := 0;
  ffelder.Feld[0] := LRecord;
wenn also dein Property vom Typ "TFeldRecord" ist dann kannst du auch nur immer den gesamten Recored lesen oder schreiben.

meierotto 24. Jun 2005 10:34

Re: Array als Published Property
 
Ist zwar nicht mehr aktuell, aber vielen Dank Sir Thornberry :wink:
Einfach die Felder der Records einzeln als array propertys anlegen und schon gehts!


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