我有一个类,其中包含另一个类的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;对于流,所有已发布的字段都已正确保存,但列表本身并不是。
出了什么问题?
答案 0 :(得分:2)
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;
答案 1 :(得分:1)
雷米给了你一个尝试的途径。
另一种可能的方法是手动实现此列表流。
你必须
TMyElemContainerClass
TComponent
ElemList
属性published
DefineProperties
方法,该方法将声明一些虚拟的,不存在的已发布属性进行流入和流出。您甚至可以将其命名为ElemList
或您认为合适的任何其他标识符。 Delphi将使用它来代替您的TObjectList
对象。从这里探索文档:http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Classes.TComponent.DefineProperties
在How to use DefineProperties in a custom Class Object for Arrays - Delphi
中查看许多(实际上有很多)示例中的一个(使用数组而不是列表,但想法是相同的)