Наследование свойств класса имеет последствия: невозможность редактирования унаследованных свойств. И это правильно: редактирование должно производиться только там, где были объявлено данное свойство. Но в конструкторе Data Keeper некоторые параметры свойства класса могут отличаться у разных классов, например видимость и порядок следования свойства в табличном представлении списка объектов. Или наличие детализации. Получается, что у свойства класса должны быть независимые параметры для каждого класса.

Этого можно добиться, если добавить ещё одну таблицу vproperty и перенести в неё такие параметры, как порядок следования, видимость и другие, которые нам понадобятся в скором времени для улучшения алгоритма генерации формы редактирования.

Изменения структуры данных потребовало не только переписать код скриптов и SQL-запросы, но и решить вопрос с формой редактирования свойств класса. Обычно в MVDB для каждой таблицы используется отдельная форма редактирования. Но в нашем случае это было бы не удобно для пользователя. Поэтому я решил “вклеить” одну форму редактирования в другую с помощью процедуры Form_ShowOnWinControl() из модуля VClass\Forms.pas.

На основной форме редактирования efmCProperty (1) добавляем панель panVProperty (2), размер которой должен быть таким, чтобы на ней поместилась дополнительная форма редактирования efmVProperty. Точнее – та часть формы, на которой находится элемент grbView, содержащий компоненты для редактирования таблицы vproperty.

На форме efmVProperty кроме группы с компонентами для редактирования параметров свойств (1), находятся невидимые поля (2), связывающие форму со свойством (edtIDCProperty) и классом (edtIDClass). Кнопка btnSave (3) спрятана за группу grbView – если сделать её невидимой, то её нельзя будет “нажать” с помощью скрипта. Её свойство Action (4) настроено на сохранение данных (5) в таблицу vproperty (6). Обязательно снимите флажок “Закрыть текущую форму после сохранения”, чтобы форма efmVProperty оставалась видимой внутри формы efmСProperty.

Привязку выполняем в процедуре UserApp_InitForm:

...
Form_ShowOnWinControl( efmVProperty, efmCProperty.panVProperty ); // вторая половина формы редактирования
...Code language: Delphi (delphi)

Обработчик onShow для формы efmCProperty необходимо немного доработать. Для того, чтобы данные на дополнительной форме прогрузились из базы, нужно найти ID записи, которая вычисляется с помощью запроса. Либо проинициализировать форму для добавления новой записи. для этого я добавил вспомогательную процедуру NewRecord.

Здесь же находится блокировка редактирования основных данных для случая, если мы открыли форму редактирования унаследованного свойства класса.

procedure efmCProperty_OnShow (Sender: TObject; Action: string);
// отображение формы редактирования свойств класса
var
  tmpID: integer;
  tmpSQL: string;

  procedure NewRecord;
  // новая запись
  begin
    efmVProperty.NewRecord('vproperty');
    efmVProperty.edtIDClass.Text := frmCProperty.edtIDClass.Text;
    efmVProperty.edtCaption.Text := efmCProperty.edtName.Text;
    // добавить номер параметра
    efmVProperty.edtGridOrderNum.Value := frmCProperty.tgrMain.RowCount + 1;
    efmVProperty.edtFieldOrderNum.Value := frmCProperty.tgrMain.RowCount + 1;
  end;

begin
  if Action = 'NewRecord' then
  begin // новая запись
    // основные свойства
    efmCProperty.edtClassID.Value := frmCProperty.edtIDClass.Value;
    if frmCProperty.tgrMain.RowCount = 0 then // не очень очевидный случай - первое свойство - имя для отображения...
      efmCProperty.chbIsName.Checked := True;
    efmCProperty.cmbPType.dbItemID := 1;
    // вспомогательные
    NewRecord;
  end
  else
  begin // существующая запись - загрузить доп. данные
    tmpSQL := 'SELECT id FROM vproperty WHERE id_class = '+frmCProperty.edtIDClass.Text+' AND id_cproperty = '+IntToStr(efmCProperty.btnSave.dbGeneralTableId);
    tmpID := SQLExecute( tmpSQL ) ;
    if tmpID = 0 then
      NewRecord
    else
      efmVProperty.ShowRecord('vproperty',tmpID);
  end;
  // редактировать элементы структуры можно только при редактировании класса, где они объявлены
  if frmCProperty.edtIDClass.Text = efmCProperty.edtClassID.Text then
  begin
    efmCProperty.grbStructure.Caption := ' Структура ';
    efmCProperty.grbStructure.Enabled := True;
    efmCProperty.edtName.SetFocus;
  end
  else
  begin
    efmCProperty.grbStructure.Caption := ' Структура (просмотр) ';
    efmCProperty.grbStructure.Enabled := False;
    efmVProperty.edtCaption.SetFocus;
  end;
end;Code language: Delphi (delphi)

Вторая доработка касается кнопки сохранения данных основной формы редактирования. Необходимо добавить обработчик события onAfterClick, в котором вызвать сохранение данных на дополнительной форме.

procedure efmCProperty_btnSave_OnAfterClick (Sender: TObject);
begin
  efmVProperty.edtIDCProperty.Value := efmCProperty.btnSave.dbGeneralTableId; // связываем
  efmVProperty.btnSave.Click; // сохраняем
  efmCProperty.Close; // предыдущая команда сбивает MVDB с толку, поэтому нужно закрывать форму
end;
Code language: JavaScript (javascript)

Итоги

Возможно, такое решение кому-то покажется сложным: вместо комбинирования форм можно было выполнить добавление или редактирование данных в таблице vproperty с помощью SQL-запросов и скриптов, но я старался минимизировать код, который придется менять в случае каких-либо доработок, и по максимуму использовать возможности самого MVDB.

Добавлена блокировка редактирования структуры, если свойство класса унаследовано (1). Параметры отображения (2) привязываются к классу. Добавлено раздельное управление порядка следования, видимости и ширины для табличного представления (3) и для компонентов на форме редактирования (4).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *