我正在一个集合项中创建一组属性。每个项目根据其类型有一组不同的属性:
type
TMyProps = class(TPersistent)
private
Fcommom: boolean;
procedure Setcommom(const Value: boolean);
published
property commom: boolean read Fcommom write Setcommom;
end;
TMyPropsClass = class of TMyProps;
TFieldPropsFloat = class(TMyProps)
private
FDecimalplaces: integer;
procedure SetDecimalplaces(const Value: integer);
published
property Decimalplaces: integer read FDecimalplaces write SetDecimalplaces;
end;
TFieldPropsStr = class(TMyProps)
private
FLength: integer;
procedure SetLength(const Value: integer);
published
property Length: integer read FLength write SetLength;
end;
TMyCollection = class(TOwnedCollection)
end;
TMyItem = class(TCollectionItem)
private
FMyPropsClass: TMyPropsClass;
FMyProps: TMyProps;
procedure ReadMyProps(Reader: TReader);
procedure WriteMyProps(Writer: TWriter);
procedure RecreateMyProps;
procedure SetMyProps(const Value: TMyProps);
procedure SetMyPropsClass(const Value: TMyPropsClass);
protected
procedure DefineProperties(Filer: TFiler); override;
public
procedure AfterConstruction; override;
published
property MyPropsClass: TMyPropsClass read FMyPropsClass write SetMyPropsClass;
property MyProps: TMyProps read FMyProps write SetMyProps stored false;
end;在“”TMyItem“”中,加载写入“”.dfm“”文件的属性时出错,因为“”MyProps“”尚未使用尚未从“”.dfm“”加载的“”MyPropsClass“”属性生成“”
如何解决?这是最好的方法吗?
编辑:此外,我正在尝试遵循Remy Lebeau给我的建议(评论如下),但是,我不能写下列表中的每一项。
///...
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TMyComponent]);
end;
procedure TMyItem.AfterConstruction;
begin
inherited;
FMyPropsClass := TFieldPropsStr;
RecreateMyProps;
end;
procedure TMyItem.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('MyProps', ReadMyProps, WriteMyProps, True);
end;
type
TReaderAccess = class(TReader);
TWriterAccess = class(TWriter);
procedure TMyItem.ReadMyProps(Reader: TReader);
begin
MyProps := TMyPropsClass(FindClass(Reader.ReadString)).Create;
Reader.CheckValue(vaCollection);
Reader.ReadListBegin;
while not Reader.EndOfList do
TReaderAccess(Reader).ReadProperty(MyProps);
Reader.ReadListEnd;
Reader.ReadListEnd;
end;
procedure TMyItem.RecreateMyProps;
begin
if FMyProps <> nil then
FMyProps.Free;
FMyProps := FMyPropsClass.Create;
end;
procedure TMyItem.SetMyProps(const Value: TMyProps);
begin
FMyProps := Value;
end;
procedure TMyItem.SetMyPropsClass(const Value: TMyPropsClass);
begin
if FMyPropsClass <> Value then
begin
FMyPropsClass := Value;
RecreateMyProps;
end;
end;
procedure TMyItem.WriteMyProps(Writer: TWriter);
begin
Writer.WriteString(MyProps.ClassName); //if comments this line, write fine
TWriterAccess(Writer).WriteValue(vaCollection);
Writer.WriteListBegin;
Writer.WriteProperties(MyProps);
Writer.WriteListEnd;
Writer.WriteListEnd;
end;
{ TMyProps }
procedure TMyProps.Setcommom(const Value: boolean);
begin
Fcommom := Value;
end;
{ TFieldPropsFloat }
procedure TFieldPropsFloat.SetDecimalplaces(const Value: integer);
begin
FDecimalplaces := Value;
end;
{ TFieldPropsStr }
procedure TFieldPropsStr.SetLength(const Value: integer);
begin
FLength := Value;
end;
{ TButton1 }
procedure TMyComponent.AfterConstruction;
begin
inherited;
FMyCollection := TMyCollection.Create(Self, TMyItem);
end;
procedure TMyComponent.SetMyCollection(const Value: TMyCollection);
begin
FMyCollection := Value;
end;如何正确地为集合的每一项实现ReadMyProps和WriteMyProps过程?
发布于 2020-01-22 04:54:03
将MyProps属性标记为stored=false (或者根本不将其设置为published ),然后覆盖虚拟DefineProperties()方法以手动流式传输MyProps数据。请参阅Embarcadero的DocWiki中的Storing and Loading Unpublished Properties: Overriding the DefineProperties Method,以及Delphi Codesmith博客上的Streaming non-published TPersistent Properties – A Better Way。
例如:
type
TMyItem = class(TCollectionItem)
private
procedure ReadMyProps(Reader: TReader);
procedure WriteMyProps(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
published
MyPropsClass: TMyPropsClass;
MyProps: TMyProps stored false;
end;
procedure TMyItem.DefineProperties(Filer: TFiler);
begin
inherited DefineProperties(Filer);
Filer.DefineProperty('MyProps', ReadMyProps, WriteMyProps, True);
end;
type
TReaderAccess = class(TReader);
TWriterAccess = class(TWriter);
procedure TMyItem.ReadMyProps(Reader: TReader);
begin
MyProps := TMyPropsClass(FindClass(Reader.ReadString)).Create;
Reader.CheckValue(vaCollection);
Reader.ReadListBegin;
while not Reader.EndOfList do
TReaderAccess(Reader).ReadProperty(MyProps);
Reader.ReadListEnd;
Reader.ReadListEnd;
end;
procedure TMyItem.WriteMyProps(Writer: TWriter);
begin
Writer.WriteString(MyProps.ClassName);
TWriterAccess(Writer).WriteValue(vaCollection);
Writer.WriteListBegin;
Writer.WriteProperties(MyProps);
Writer.WriteListEnd;
Writer.WriteListEnd;
end;https://stackoverflow.com/questions/59739699
复制相似问题