Delphi - сбориник статей

       

Подмена стандартного Inplace-Editor'a в DBGrid отдельным компонентом на примере TDBComboBox.


Для того, чтобы вместо стандартного редактора в колонке DBGrid'а появился другой компонент, проделаем несколько действий:

  • Создадим отдельный компонент, который будет редактором (в примере используется TDBComboBox). При его создании следует установить свойство Visible в False, для того, чтобы вне грида он не отображался.
    Компонент DBComboBox выбран для того, чтобы обеспечить автоматическую связь с данными в DataSet'е, который отображается в Grid'е.

При создании компонента, свяжем его с тем же набором данных, что и Grid, в качестве DataField установим имя того поля, редактор которого в гриде мы хотим подменять. Вместо создания вручную компонент можно положить на форму в design-time

FEditor := TDBComboBox.Create(Self); FEditor.Parent := Self; FEditor.Visible := false; FEditor.Style := csDropdownList; FEditor.DataSource := DBGrid.DataSource; FEditor.DataField := 'STATE';
В данном примере список ComboBox'а заполняется значениями из Picklist нужного столбца грида.

for I:=0 to Pred(DBGrid.Columns.Count) do if DBGrid.Columns[I].Field.FieldName = FEditor.DataField then begin { Присвоение списка PickList списку строк ComboBox'a }

FEditor.Items.Assign(DBGrid.Columns[I].PickList); Break; end;
  • Показывать этот компонент мы будем в обработчике события OnDrawColumnCell, когда нужная колонка получает фокус (рис. 2).

  • рис. 2

    procedure TForm1.DBGridDrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin if (gdFocused in State) then if (Column.Field.FieldName = FEditor.DataField) then begin { Вместо стандартного InplaceEditor'а показываем ComboBox } FEditor.Left := Rect.Left + DBGrid.Left; FEditor.Top := Rect.Top + DBGrid.top; FEditor.Width := Rect.Right - Rect.Left + 2; FEditor.Visible := True; end; end;

    Для того, чтобы нарисованный компонент не оставался видимым после того, как нужная ячейка потеряет фокус, спрячем его в обработчике события ColExit

    procedure TForm1.DBGridColExit(Sender: TObject); begin { При выходе с поля ComboBox надо скрыть } if DBGrid.SelectedField.FieldName = FEditor.DataField then FEditor.Visible := false; end;

    Для того, чтобы менять значение поля можно было не только выбором мышью из списка, но и с клавиатуры, необходимо передавать ComboBox'у нажатия клавиш DBGrid'а, при редактировании поля. Это можно сделать как в обработчике события OnKeyPress DBGrid'a, так и в обработчике OnKeyDown. Я приведу пример обработчика OnKeyPress.

    procedure TForm1.DBGridKeyPress(Sender: TObject; var Key: Char); begin { Передаем все нажатия клавиш в InplaceEditor'е созданному ComboBox'у } if (Key <> chr(9)) then if (DBGrid.SelectedField.FieldName = FEditor.DataField) then begin FEditor.SetFocus; SendMessage(FEditor.Handle, WM_CHAR, word(Key), 0); end; end;

    В примере использован TDBComboBox, по аналогии с ним можно использовать для редактирования и другие компоненты. Ниже на рисунке показан пример, где аналогичным образом в грид встроен TDBDateEdit для редактирования полей типа "дата":



    Содержание раздела