我有一个包含另一个类的对象的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对象被“保存”到一个流中时,所有已发布的字段都被正确地保存了,但是列表本身却没有。
怎么了?
发布于 2017-09-28 23:40:37
TObjectList不是一个可流式处理的类。仅仅因为您在published属性中使用它并不意味着流系统自动知道如何流它。如果您使用的是DFM流系统,则只有从TPersistent派生的类是可流的,而TObjectList不是。你必须为它实现定制的流逻辑。
考虑将您的设计改为使用TCollection和TCollectionItem,例如:
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;发布于 2017-09-29 00:55:08
雷米给了你一个尝试的途径。
另一种可能的方式是手动实现该列表流式传输。
你将不得不
从TComponent
ElemList published TComponent
TMyElemContainerClass ElemListpublishedpublished DefineProperties方法将声明一些虚拟的、不存在的已发布属性以流方式传入和传出。您甚至可以将其命名为ElemList或您认为合适的任何其他标识符。它将由Delphi使用,而不是上述虚拟财产的TObjectList object.
从此处浏览文档:http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Classes.TComponent.DefineProperties
在How to use DefineProperties in a custom Class Object for Arrays - Delphi上可以看到许多(确实有很多)示例(使用数组而不是列表,但思想是相同的)
https://stackoverflow.com/questions/46472014
复制相似问题