不保存TObjectList <myclass>字段到类中

时间:2017-09-28 14:44:42

标签: delphi

我有一个类,其中包含另一个类的TObjectList<T>个对象列表。

TMyElementClass = class (TPersistent)
private
  ....
public
  ....
end;

TMyElemContainerClass = class (TPersistent)
private
  fElemList: TObjectList<TMyElementClass>;
  ...
published
  ElemList: TObjectList<TMyElementClass> read fElemList write fElemList;
end;

var
  Elements: TMyElemContainerClass;

我注册了两个班级:

   System.Classes.RegisterClass (TMyElemContainerClass);
   System.Classes.RegisterClass (TMyElementClass);

问题是,Elements对象被&#34;保存&#34;对于流,所有已发布的字段都已正确保存,但列表本身并不是。

出了什么问题?

2 个答案:

答案 0 :(得分:2)

TObjectList不是一个可流媒体的课程。仅仅因为你在published属性中使用它并不意味着流系统自动知道如何流式传输它。如果您使用的是DFM流式传输系统,则只有派生自TPersistent的类才可以流式传输,但TObjectList不会。您必须为它实现自定义流逻辑。

请考虑将设计更改为使用TCollectionTCollectionItem,例如:

TMyElementClass = class (TCollectionItem)
private
  ...
public
  ...
published
  ...
end;

TMyElemCollectionClass = class (TCollection)
private
  function GetElem(Index: Integer): TMyElementClass;
  procedure SetElem(Index: Integer; Value: TMyElementClass);
public
  constructor Create; reintroduce;
  function Add: TMyElementClass; reintroduce;
  function Insert(Index: Integer): TMyElementClass; reintroduce;
  property Elements[Index: Integer]: TMyElementClass read GetElem write SetElem; default;
end;

TMyElemContainerClass = class (TPersistent)
private
  fElemList: TMyElemCollectionClass;
  procedure SetElemList(Value: TMyElemCollectionClass);
  ...
public
  constructor Create;
  destructor Destroy; override;
  ...
published
  ElemList: TMyElemCollectionClass read fElemList write SetElemList;
end;

...

constructor TMyElemCollectionClass.Create;
begin
  inherited Create(TMyElementClass);
end;

function TMyElemCollectionClass.GetElem(Index: Integer): TMyElementClass;
begin
  Result := TMyElementClass(inherited GetItem(Index));
end;

procedure TMyElemCollectionClass.SetElem(Index: Integer; Value: TMyElementClass);
begin
  inherited SetItem(Index, Value);
end;

function TMyElemCollectionClass.Add: TMyElementClass;
begin
  Result := TMyElementClass(inherited Add);
end;

function TMyElemCollectionClass.Insert(Index: Integer): TMyElementClass;
begin
  Result := TMyElementClass(inherited Insert(Index));
end;

constructor TMyElemContainerClass.Create;
begin
  inherited;
  fElemList := TMyElemCollectionClass.Create;
end;

destructor TMyElemContainerClass.Destroy;
begin
  fElemList.Destroy;
  inherited;
end;

procedure TMyElemContainerClass.SetElemList(Value: TMyElemCollectionClass);
begin
  fElemList.Assign(Value);
end;

答案 1 :(得分:1)

雷米给了你一个尝试的途径。

另一种可能的方法是手动实现此列表流。

你必须

  1. TMyElemContainerClass
  2. 派生您的TComponent
  3. ElemList属性
  4. 中删除published
  5. 覆盖DefineProperties方法,该方法将声明一些虚拟的,不存在的已发布属性进行流入和流出。您甚至可以将其命名为ElemList或您认为合适的任何其他标识符。 Delphi将使用它来代替您的TObjectList对象。
  6. 为所述虚拟属性实现面向流的读写器方法,它们应遍历所有项目并保存/加载它们。
  7. 从这里探索文档:http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Classes.TComponent.DefineProperties

    How to use DefineProperties in a custom Class Object for Arrays - Delphi

    中查看许多(实际上有很多)示例中的一个(使用数组而不是列表,但想法是相同的)