在代码中设置 ADT 字段

Setting up ADT fields in code

我正在试验一个简单的 ClientDataSet 项目,该项目使用名为 Address 的 TADTField,它包含两个子字段 Line1 和 City,它们都是字符串,大小为 20。CDS 连接到 DBGrid 和 DBNavigator。

如果我使用 Object Inspector 中的 TFieldDefs 和 ADT 字段的 ChildDefs 属性 设置 CDS,则项目可以正常编译和执行。

但是,如果我尝试在代码中设置 ATD 字段及其子字段,我会遇到两个问题:

显然我做错了什么,但我看不出是什么。

这是我的代码:

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 编辑器以普通方式创建 Line1City 字段,然后 select 它们依次打开 OI 并设置它们的 ParentField 属性.我想您会发现它们和 Address 字段将正确显示在您的网格中,并且关闭时的 AV 将消失。