我尝试使用一个名为Address的TADTField的简单ClientDataSet项目,该项目包含两个子字段Line1和City,两个字段都是字符串,大小为20. CDS连接到DBGrid和DBNavigator。
如果我在Object Inspector中使用TFieldDefs和ADT字段的ChildDefs属性设置CDS,则项目编译并执行正常。
但是,如果我尝试在代码中设置ATD字段及其子代,我会遇到两个问题:
与我使用FieldDefs方法时不同,ATD" cell"不会出现在DBGrid中,因此Line1和City子字段不会显示在其中。相反,它们显示为普通字段,并且它们是重复的。有一个" Line1"专栏,然后是" City"一个,然后另一个" Line1" ...
当我关闭表单时,我会得到一个"双倍免费" AV内部第二次(?)调用TFields.Destroy。
很明显,我做错了什么,但我看不出它是什么。
这是我的代码:
procedure TForm1.FormCreate(Sender: TObject);
var
ADTField : TADTField;
Field : TField;
begin
// at this point, the clientDataSet has no TFields or TFieldDefs
Field := TIntegerField.Create(nil);
Field.FieldName := 'ID';
Field.DataSet := ClientDataset1;
ADTField := TADTField.Create(nil);
ADTField.FieldName := 'Address';
ADTField.DataSet := ClientDataset1;
Field := TStringField.Create(nil);
Field.FieldName := 'Line1';
Field.Size := 20;
Field.DataSet := ClientDataset1;
ADTField.Fields.Add(Field);
Field := TStringField.Create(nil);
Field.FieldName := 'City';
Field.Size := 20;
Field.DataSet := ClientDataset1;
ADTField.Fields.Add(Field);
ClientDataset1.CreateDataSet;
ClientDataset1.Insert;
ClientDataset1.FieldByName('ID').AsInteger := 1;
try
ADTField.Fields.FieldByName('Line1').AsString := '1, Railway Cuttings';
ADTField.Fields.FieldByName('City').AsString := 'London';
except
end;
ClientDataset1.Post;
end;
这是项目的整个代码。我正在使用D7。
答案 0 :(得分:3)
当我第一次尝试使用ADT字段时,我记得被类似的东西所欺骗:虽然IDE中的TFieldDefs编辑器有一种将子FieldDef添加到TADTField的明显方法,但IDE的TFields编辑器中没有对应的。
无论如何,我认为你并没有“正确地”养育你想成为ADT孩子的两个领域。不需要调用ADTField.Fields.Add
,而是需要通过字段本身来设置ParentField
属性:
Field := TStringField.Create(ClientDataset1);
Field.FieldName := 'Line1';
Field.Size := 20;
Field.DataSet := ClientDataset1;
// ADTField.Fields.Add(Field);
Field.ParentField := ADTField;
如果您正在设置TField而不是TFieldDefs,那么顺便说一句,您将如何在IDE中执行此操作。您可以使用TFields编辑器以普通方式创建Line1
和City
字段,然后依次在OI上选择它们并设置其ParentField
属性。我想你会发现它们和Address
字段会正确地显示在你的网格中,并且关机时AV会消失。