首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有在TCollection中声明的TComponent的序列化?

没有在TCollection中声明的TComponent的序列化?
EN

Stack Overflow用户
提问于 2012-01-14 15:01:26
回答 1查看 1.1K关注 0票数 1

是否可以序列化没有封装在TCollection中的TComponent?

例如,我有一个定制的TCollection。我不能在我的TMemoryStream.WriteComponent后代上使用TCollection ()。只有当我将集合封装在TComponent中,然后编写这个组件时,它才能工作。

从技术上讲,没有问题,但是声明一个TComponent (只有拥有一个TCollection )似乎有点奇怪。

代码语言:javascript
复制
TMyCustomCollection = Class(TCollection) // not serializable ?
  //...
End;

TMyCustomCollectionCapsule = Class(TComponent) // serializable !
Private
  FMyCusColl: TMyCustomCollection;
  Procedure SetMyCusColl(Const Data: TMyCustomCollection);
Published
  Property CanBeSerialized: TMyCustomCollection Read FMyCusColl Write SetMyCusColl
End;

也许我只是错过了Delphi的一个特性?TPersistent后代是否可以在不被封装在TComponent中的情况下进行流?

EN

回答 1

Stack Overflow用户

发布于 2012-01-14 18:18:31

可以通过定义如下的另一个TCollection ( TComponent子代)序列化未封装在TComponent中的TComponent:

代码语言:javascript
复制
type
  TCollectionSerializer = class(TComponent)
  protected
    FCollectionData: string;
    procedure DefineProperties(Filer: TFiler); override;
  public
    procedure WriteData(Stream: TStream);
    procedure ReadData(Stream: TStream);
    //
    procedure LoadFromCollection(ACollection: TCollection);
    procedure SaveToCollection(ACollection: TCollection);
  end;

DefinePropertiesWriteDataReadData实现详细信息:

代码语言:javascript
复制
procedure TCollectionSerializer.WriteData(Stream: TStream);
var
  StrStream: TStringStream;
begin
  StrStream:=TStringStream.Create;
  try
    StrStream.WriteString(FCollectionData);
    Stream.CopyFrom(StrStream,0);
  finally
    StrStream.Free;
  end;
end;

procedure TCollectionSerializer.ReadData(Stream: TStream);
var
  StrStream: TStringStream;
begin
  StrStream:=TStringStream.Create;
  try
    StrStream.CopyFrom(Stream,0);
    FCollectionData:=StrStream.DataString;
  finally
    StrStream.Free;
  end;
end;

procedure TCollectionSerializer.DefineProperties(Filer: TFiler);
begin
  inherited;
  //
  Filer.DefineBinaryProperty('CollectionData', ReadData, WriteData,True);
end;

LoadFromCollectionSaveToCollection模板

代码语言:javascript
复制
procedure TCollectionSerializer.LoadFromCollection(ACollection: TCollection);
var
  CollectionStream: TStream;
begin
  CollectionStream:= TCollectionStream.Create(ACollection);
  try
    ReadData(CollectionStream)
  finally
    CollectionStream.Free;
  end;
end;

procedure TCollectionSerializer.SaveToCollection(ACollection: TCollection);
var
  CollectionStream: TStream;
begin
  CollectionStream:= TCollectionStream.Create(ACollection);
  try
    WriteData(CollectionStream);
  finally
    CollectionStream.Free;
  end;
end;

关于TCollectionStream

它应该是一个TStream后代,它有一个以TCollection作为参数的富创建者,并且设计成类似于TFileStream。你必须实现它。免责声明:我从未对此进行过测试,但我可以看出TFileStream可以工作(用于流外部文件)。

结论:

这个组件的灵感来自VCL方式,在DFM中序列化Delphi (RCData)下的外部文件。它必须与组件编辑器(也必须基于TComponentEditor实现)一起注册,在设计时执行序列化。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8863019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档