Настройка полей ADT в коде

#delphi #tclientdataset

#delphi #tclientdataset

Вопрос:

Я экспериментирую с простым проектом ClientDataSet, который использует TADTField с именем Address, который содержит два подполя, Line1 и City, оба из которых представляют собой строки размером 20. CDS подключен к DBGrid и DBNavigator.

Если я настрою CDS, используя TFieldDefs в инспекторе объектов и свойство ChildDefs поля ADT, проект скомпилируется и будет выполнен нормально.

Однако, если я попытаюсь настроить поле ATD и его дочерние элементы в коде, я получаю две проблемы:

  • В отличие от того, когда я использую метод FieldDefs, «ячейка» ATD не отображается в DBGrid, поэтому подполя Line1 и City не отображаются внутри него. Вместо этого они отображаются как обычные поля и дублируются. Есть один столбец «Line1», затем столбец «Город», затем еще один «Line1″…

  • Когда я закрываю форму, я получаю AV «без двойных» внутри второго (?) Вызова TFields.Уничтожить.

Очевидно, я делаю что-то не так, но я не вижу, что это такое.

Вот мой код :

 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.

Ответ №1:

Я помню, как меня одурачило нечто подобное, когда я впервые попробовал ADT-поля: хотя редактор TFieldDefs в IDE имеет очевидный способ добавления дочерних полей полей в TADTField, в редакторе TFields IDE нет аналога.

В любом случае, я думаю, вы не совсем правильно «воспитываете» два поля, которые вы хотите сделать дочерними для 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;
  

И это, кстати, то, как вы сделали бы это в IDE, если бы вы настраивали TFields вместо TFieldDefs. Вы должны создать свои Line1 City поля и обычным способом, используя редактор TFields, затем по очереди выбирать их в OI и устанавливать их ParentField свойства. Я думаю, вы обнаружите, что они и Address поле будут отображаться в вашей сетке правильно, и AV при завершении работы исчезнет.