reallike,有些东西说穿并不希奇.呵呵.看看这儿的代码.TReader.ReadPropValue看见了那一长串难看的CASE了吗? ............. tkClass: case NextValue of vaNil: begin ReadValue; SetOrdProp(Instance, PropInfo, 0) end; vaCollection: begin ReadValue; ReadCollection(TCollection(GetOrdProp(Instance, PropInfo))); end else SetObjectIdent(Instance, PropInfo, ReadIdent); end; ...............
我想也是,运行时TFields保存的应该是用TFieldList进行初始化之后的。要不然FindField就找不到内容了。TForm1属性具有的TField应该是独立的。我想我也得建立一个列表了。老兄们,我做的类似这样 object ADOTable1: TADOTable Connection = ADOConnection1 TableName = 'Customers' Left = 200 Top = 90 end object ADOTable1Region: TWideStringField FieldName = 'Region' Size = 15 end object ADOTable1PostalCode: TWideStringField FieldName = 'PostalCode' Size = 10 end是平级的关系,但是我现在需要这样的关系: object ADOTable1: TADOTable Connection = ADOConnection1 TableName = 'Customers' Left = 200 Top = 90 object ADOTable1Region: TWideStringField FieldName = 'Region' Size = 15 end object ADOTable1PostalCode: TWideStringField FieldName = 'PostalCode' Size = 10 end end这样也是TDataSet做到的,我不知道为什么做不到这种子集的关系。
TFields里面列表不是同TFields一起串行化的。 而是在串行化TField的时候。。它的调用序列如下:TReader.ReadComponent TField.ReadState TField.SetDataSet 。 if (ADataSet <> nil) and (FParentField = nil) then begin if FieldKind = fkAggregate then ADataSet.FAggFields.Add(Self) else ADataSet.FFields.Add(Self);//这儿把自己加进Fields去的。 end; 。 TFields.Add
另外,我还是不明白TCollection怎么把item保存到dfm中的。比如这个: object ADODataSet1: TADODataSet FieldDefs = < item Name = 'ADODataSet1Field1' end item Name = 'ADODataSet1Field2' end item Name = 'ADODataSet1Field3' end> StoreDefs = True Left = 330 Top = 150 end怎么回事呢?这个是我最最不明白的一件事情。
to 短歌兄TFieldDef保存的是字段类型TFieldType,不是TField的东西。然后通过DefaultFieldClasses,这么一个数组得到类引用来建立字段的。
我知道为什么TField可以加在DataSet内了。procedure TField.ReadState(Reader: TReader); begin inherited ReadState(Reader); if Reader.Parent is TObjectField then ParentField := TObjectField(Reader.Parent) else if Reader.Parent is TDataSet then DataSet := TDataSet(Reader.Parent); end;DataSet做了他的Parent……
.............
tkClass:
case NextValue of
vaNil:
begin
ReadValue;
SetOrdProp(Instance, PropInfo, 0)
end;
vaCollection:
begin
ReadValue;
ReadCollection(TCollection(GetOrdProp(Instance, PropInfo)));
end
else
SetObjectIdent(Instance, PropInfo, ReadIdent);
end;
...............
>TFields = class(TObject)
>本来是想仿照这个做的。但是为什么这个不行?说明你仿照得不对。^O^
不过要存到DFM里,还是应该从TPersistent继承会比较简单一点,不然要自己处理一堆序列化的工作。
在字段编辑器编辑永久字段后,这些永久字段是会被加入TFORM1的published 属性,
它们的串行化,看来是不依赖它们的容器TFields了。所以,它的TFields可以继承于TOBJECT,你的却没有成功。
这样虽然TField被保存了,但TFields还是要自己实现序列化,否则TField的列表还是没有保存。
Connection = ADOConnection1
TableName = 'Customers'
Left = 200
Top = 90
end
object ADOTable1Region: TWideStringField
FieldName = 'Region'
Size = 15
end
object ADOTable1PostalCode: TWideStringField
FieldName = 'PostalCode'
Size = 10
end是平级的关系,但是我现在需要这样的关系: object ADOTable1: TADOTable
Connection = ADOConnection1
TableName = 'Customers'
Left = 200
Top = 90
object ADOTable1Region: TWideStringField
FieldName = 'Region'
Size = 15
end
object ADOTable1PostalCode: TWideStringField
FieldName = 'PostalCode'
Size = 10
end
end这样也是TDataSet做到的,我不知道为什么做不到这种子集的关系。
而是在串行化TField的时候。。它的调用序列如下:TReader.ReadComponent
TField.ReadState
TField.SetDataSet
。
if (ADataSet <> nil) and (FParentField = nil) then
begin
if FieldKind = fkAggregate then
ADataSet.FAggFields.Add(Self) else
ADataSet.FFields.Add(Self);//这儿把自己加进Fields去的。
end;
。
TFields.Add
FieldDefs = <
item
Name = 'ADODataSet1Field1'
end
item
Name = 'ADODataSet1Field2'
end
item
Name = 'ADODataSet1Field3'
end>
StoreDefs = True
Left = 330
Top = 150
end怎么回事呢?这个是我最最不明白的一件事情。
TField.ReadState
TField.SetDataSet要学的东西可是太多了……
串行化生成的就是你要的那样了:)
再刺激你一下,这是一个包含COLLECTION属性成员的COMPONENT,存入DFM的调用序列.TComponent.WriteState
TWriter.WriteData
TWriter.WriteProperties
TWriter.WriteProperty
WriteObjectProp
WriteCollectionProp
WriteCollection
TWriter.WriteCollection
begin
inherited ReadState(Reader);
if Reader.Parent is TObjectField then
ParentField := TObjectField(Reader.Parent)
else if Reader.Parent is TDataSet then
DataSet := TDataSet(Reader.Parent);
end;DataSet做了他的Parent……