Einzelnen Beitrag anzeigen

Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#6

Re: TCollection und TCollectionItem

  Alt 26. Mai 2004, 16:46
Zitat von maximov:
Mir gefällt das mit der dummy-compo eigentlich ganz gut UND du müsstest auch nicht mit assign arbeiten, sondern könntest direkt die referenz zuweisen. Der vorteil wäre dann auch, das man im container noch zusätzliche properties definieren kann, die nicht in jedem item auftauchen dürfen/sollten - quasi globale infos...
Wenn ich es richtig verstehe, sollen
über diesen Weg die published properties der TCollection gespeichert werden. Leider bekomme ich das nicht hin. Wie meinst Du das genau?

Die property Collectionname in TAddressItems wird nicht mitgespeichert
Delphi-Quellcode:
unit Collection;

interface

uses SysUtils, classes;

Type

   {TNumber repräsentiert je einen Eintrag in TNumbers}
   TNumber = class(TCollectionItem)
   private
    FNumber : Integer;
   public
     procedure Assign(Source : TPersistent); override; // muss überschrieben werden
   published
     property Number : Integer read FNumber write FNumber;
   end;

   TNumbers = class(TCollection)
   private
    function GetItem(X: Integer): TNumber;
    procedure SetItem(X: Integer; const Value: TNumber);
   public
     constructor Create;
     function Add : TNumber;
     property Items[X : Integer] : TNumber read GetItem write SetItem; default;
   end;

   {TAddressItem repräsentiert je einen Eintrag in TAddressItems
    Numbers ist hier ebenfalls ein Collection. Numbers wird
    automatisch gespeichert !!!}

   TAddressItem = class(TCollectionItem)
   private
    FFirstname : String;
    FNumbers : TNumbers;
   public
     constructor Create(Collection: TCollection); override;
     destructor Destroy; override;
     procedure Assign(Source : TPersistent); override; // muss überschrieben werden
   published
     property Firstname : String read FFirstname write FFirstname;
     property Numbers : TNumbers read FNumbers write FNumbers;
   end;

   {Das ist unsere Basisliste}
   TAddressItems = class(TCollection)
   private
    FCollectionName : String;
    function GetItem(X: Integer): TAddressItem;
    procedure SetItem(X: Integer; const Value: TAddressItem);
   public
     constructor Create;
     procedure Assign(Source : TPersistent); override;
     function Add : TAddressItem;
     procedure SaveToFile(const Filename : TFilename);
     procedure LoadFromFile(const Filename : TFilename);
     procedure SaveToStream(Stream : TStream);
     procedure LoadFromStream(Stream : TStream);
     property Items[X : Integer] : TAddressItem read GetItem write SetItem; default;
   published
     property CollectionName : String read FCollectionName write FCollectionName;
   end;

   {TAddressDummy ist ein Dummy, der nur benötigt wird, um
    TAddressItems zu speichern. Siehe TAddressItems.SaveToStream.
    Da das Streamingsystem erst ab TComponent greift brauchen wir
    hier diesen Dummy}

   TAddressDummy = class(TComponent)
   private
     FItems : TAddressItems;
   published
     property Items : TAddressItems read FItems write FItems;
   end;

implementation

{ TAddressItem }

procedure TAddressItem.Assign(Source: TPersistent);
begin
  If Source is TAddressItem then
    begin
    FFirstname:=TAddressItem(Source).Firstname;
    FNumbers.Assign(TAddressItem(Source).Numbers);
    end
      else
        inherited Assign(Source);
end;

constructor TAddressItem.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  FNumbers:=TNumbers.Create;
end;

destructor TAddressItem.Destroy;
begin
  FNumbers.Free;
  inherited Destroy;
end;

{ TAddressItems }

function TAddressItems.Add: TAddressItem;
begin
  Result:=inherited Add as TAddressItem;
end;

constructor TAddressItems.Create;
begin
  inherited Create(TAddressItem);
end;

function TAddressItems.GetItem(X: Integer): TAddressItem;
begin
  Result:=inherited GetItem(X) as TAddressItem;
end;


procedure TAddressItems.SaveToFile(const Filename: TFilename);
var
  FileStream : TFileStream;
begin
  FileStream:=TFileStream.Create(Filename,fmCreate);
  Try
    SaveToStream(FileStream);
  Finally
    FileStream.Free;
    end;
end;

procedure TAddressItems.LoadFromFile(const Filename: TFilename);
var
  FileStream : TFileStream;
begin
  Clear;
  FileStream:=TFileStream.Create(Filename,fmOpenRead);
  Try
    LoadFromStream(FileStream);
  Finally
    FileStream.Free;
    end;
end;

procedure TAddressItems.SaveToStream(Stream: TStream);
var
  AddressDummy : TAddressDummy;
begin
  AddressDummy:=TAddressDummy.Create(Nil);
  Try
    AddressDummy.Items:=Self;
    Stream.WriteComponent(AddressDummy);
  Finally
    AddressDummy.Free;
    end;
end;

procedure TAddressItems.LoadFromStream(Stream: TStream);
var
  AddressDummy : TAddressDummy;
begin
  AddressDummy:=TAddressDummy.Create(Nil);
  Try
    AddressDummy.Items:=Self;
    Stream.ReadComponent(AddressDummy);
  Finally
    AddressDummy.Free;
    end;
end;

procedure TAddressItems.SetItem(X: Integer; const Value: TAddressItem);
begin
  inherited SetItem(X,Value);
end;


procedure TAddressItems.Assign(Source: TPersistent);
begin
  If Source is TAddressItems then
    FCollectionName:=TAddressItems(Source).CollectionName
      else
        inherited Assign(Source);
end;


{ TNumber }

procedure TNumber.Assign(Source: TPersistent);
begin
  If Source is TNumber then
    begin
    FNumber:=TNumber(Source).Number;
    end
      else
        inherited Assign(Source);
end;

{ TNumbers }

function TNumbers.Add: TNumber;
begin
  Result:=inherited Add as TNumber
end;

constructor TNumbers.Create;
begin
  inherited Create(TNumber);
end;

function TNumbers.GetItem(X: Integer): TNumber;
begin
  Result:=inherited GetItem(X) as TNumber;
end;

procedure TNumbers.SetItem(X: Integer; const Value: TNumber);
begin
  inherited SetItem(X,Value);
end;

end.
I come from outer space to save the human race
  Mit Zitat antworten Zitat