在代码中设置 ADT 字段
Setting up ADT fields in code
我正在试验一个简单的 ClientDataSet 项目,该项目使用名为 Address 的 TADTField,它包含两个子字段 Line1 和 City,它们都是字符串,大小为 20。CDS 连接到 DBGrid 和 DBNavigator。
如果我使用 Object Inspector 中的 TFieldDefs 和 ADT 字段的 ChildDefs 属性 设置 CDS,则项目可以正常编译和执行。
但是,如果我尝试在代码中设置 ATD 字段及其子字段,我会遇到两个问题:
与我使用 FieldDefs 方法时不同,ATD "cell" 不会出现在 DBGrid 中,因此 Line1 和 City 子字段不会显示在其中。相反,它们显示为普通字段并且是重复的。有一个 "Line1" 列,然后是 "City" 列,然后是另一个 "Line1" ...
当我关闭表单时,我在第二次 (?) 调用 TFields.Destroy.
中得到一个 "double-free" AV
显然我做错了什么,但我看不出是什么。
这是我的代码:
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.
我记得我第一次尝试 ADT 字段时被类似的东西迷住了:虽然 IDE 中的 TFieldDefs 编辑器有一个明显的方法可以将子 FieldDef 添加到 TADTField,但 IDE 的 TFields 编辑器。
无论如何,我认为您不完全 "parenting" 您希望成为 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;
顺便说一下,如果您设置的是 TFields 而不是 TFieldDefs,那么您将如何在 IDE 中执行此操作。您将使用 TFields 编辑器以普通方式创建 Line1
和 City
字段,然后 select 它们依次打开 OI 并设置它们的 ParentField
属性.我想您会发现它们和 Address
字段将正确显示在您的网格中,并且关闭时的 AV 将消失。
我正在试验一个简单的 ClientDataSet 项目,该项目使用名为 Address 的 TADTField,它包含两个子字段 Line1 和 City,它们都是字符串,大小为 20。CDS 连接到 DBGrid 和 DBNavigator。
如果我使用 Object Inspector 中的 TFieldDefs 和 ADT 字段的 ChildDefs 属性 设置 CDS,则项目可以正常编译和执行。
但是,如果我尝试在代码中设置 ATD 字段及其子字段,我会遇到两个问题:
与我使用 FieldDefs 方法时不同,ATD "cell" 不会出现在 DBGrid 中,因此 Line1 和 City 子字段不会显示在其中。相反,它们显示为普通字段并且是重复的。有一个 "Line1" 列,然后是 "City" 列,然后是另一个 "Line1" ...
当我关闭表单时,我在第二次 (?) 调用 TFields.Destroy.
中得到一个 "double-free" AV
显然我做错了什么,但我看不出是什么。
这是我的代码:
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.
我记得我第一次尝试 ADT 字段时被类似的东西迷住了:虽然 IDE 中的 TFieldDefs 编辑器有一个明显的方法可以将子 FieldDef 添加到 TADTField,但 IDE 的 TFields 编辑器。
无论如何,我认为您不完全 "parenting" 您希望成为 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;
顺便说一下,如果您设置的是 TFields 而不是 TFieldDefs,那么您将如何在 IDE 中执行此操作。您将使用 TFields 编辑器以普通方式创建 Line1
和 City
字段,然后 select 它们依次打开 OI 并设置它们的 ParentField
属性.我想您会发现它们和 Address
字段将正确显示在您的网格中,并且关闭时的 AV 将消失。