Теперь, как и что я делал. Пишу пока под Debian Jessi x64, но будет и под Windows. Lazarus 1.6.2. Решил подменить стандартный редактор ячейки типа TPickListCellEditor, чтобы сделать доступным его OnChange.
- Код: Выделить всё
TMyPickListCellEditor = class(TPickListCellEditor)
public
property OnChange;
end;
У формы объявил переменную, где будет ссылка на экземпляр редактора
- Код: Выделить всё
fNameEditor: TCompositeCellEditor;
fPickListEditor: TMyPickListEditor;
Композитный редактор нужен, чтобы помимо ручного ввода и выпадающего списка, была кнопка для вызова справочника для подбора. Далее, при создании формы, инициализирую редактор:
- Код: Выделить всё
fPickListEditor := TMyPickListEditor.Create(Self);
fPickListEditor.Name := 'PickListEditor';
fPickListEditor.Visible := False;
fPickListEditor.AutoSize := False;
fPickListEditor.OnChange := @Self.NameChange;
//fPickListEditor.AutoComplete := True;
TStringList(fPickListEditor.Items).OwnsObject := True;
fNameEditor := TCompositeCellEditor.Create(Self)
fNameEditor.Name := 'NameEditor';
fNameEditor.Visible := False;
fNameEditor.AddEditor(fPickListEditor, alClient, True);
fNameEditor.AddEditor(G.EditorByStyle(cbsButton), alRight, False);//G - мой DBGrid
У DBGrid сел на OnSelectEditor, чтобы подставить свой редактор
- Код: Выделить всё
procedure TDocForm.GSelectEditor(Sender: TObject; Column: TColumn; var Editor: TWinControl);
begin
if SameText(Column.FieldName, 'NAME') then Editor := fNameEditor;
end;
Ну и действия при изменении текста в ячейке:
- Код: Выделить всё
procedure TDocForm.NameChange(Sender: TObject);
var
Item: TLstItem;
CB: TMyPickListCellEditor;
begin
CB := Sender as TMyPickListCellEditor;
CB.Items.Clear;
if UTF8Length(CB.Text) > 1 then
begin
IBSQL.Close;
IBSQL.SQL.Text := 'select first 11 * from tovars where upper(name) starting upper(:n)';
IBSQL.ParamByName('n').AsString := CB.Text;
IBSQL.ExecQuery;
while not IBSQL.Eof do
begin
Item := TLstItem.Create;
Item.ID := IBSQL.FieldByName('ID').AsInteger;
Item.NAME := IBSQL.FieldByName('NAME').AsString;
CB.AddItem(Item.Name, Item);
IBSQL.Next;
end;
if CB.Items.Count > 0 then CB.DroppedDown := True;
end;
end;
Теперь сам вопрос: когда список выпадает (CB.DroppedDown := True), ввод в ячейку становится недоступным. Похоже, что выпавший список получает фокус ввода. Где и что надо дописать, чтобы, после выпадания списка, можно было продолжать ввод в ячейку?
P.S. Это, так сказать, пробный код, в конечном коде будет подругому, как минимум, запрос и заполнение выпадающего списка вынесу в поток, на случай, если запрос будет долго выполняться. Ну и т.д.
Так много написал, чтоб ясно было, что и как сделал, вдруг кому пригодится мой опыт, задача ведь распространенная.