将DBLookupCombobox添加到Delphi DBGrid

时间:2015-10-02 21:50:26

标签: delphi dbgrid

我想将DBLookupCombobox添加到DBGrid中的某些列。在About.com上有一篇关于如何执行此操作的好文章here。问题是如果一个表有很多列,如果你从一列中的DBLookupCombobox中选择然后尝试向左滚动,那么组合框也会向左移动,如图所示。如何更改About.com代码以防止此行为?网络搜索显示另外两个人抱怨完全相同的问题没有解决方案。请注意,我想使用DBLookupCombobox来显示名称但输入id,因此使用简单的选项列表是行不通的。

using combobox scroll left

procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  if DBGrid1.SelectedField.FieldName = DBLookupComboBox1.DataField then
    DBLookupComboBox1.Visible := False
end;

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if (gdFocused in State) then
  begin
    if (Column.Field.FieldName = DBLookupComboBox1.DataField) then
    with DBLookupComboBox1 do
    begin
      Left := Rect.Left + DBGrid1.Left + 2;
      Top := Rect.Top + DBGrid1.Top + 2;
      Width := Rect.Right - Rect.Left;
      Width := Rect.Right - Rect.Left;
      Height := Rect.Bottom - Rect.Top;

      Visible := True;
    end;
  end
end;

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  if (key = Chr(9)) then Exit;

  if (DBGrid1.SelectedField.FieldName = DBLookupComboBox1.DataField) then
  begin
    DBLookupComboBox1.SetFocus;
    SendMessage(DBLookupComboBox1.Handle, WM_Char, word(Key), 0);
  end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 with DBLookupComboBox1 do
 begin
   DataSource := DataSource1; // -> AdoTable1 -> DBGrid1
   ListSource := DataSource2;
   DataField   := 'resource_id'; // from AdoTable1 - displayed in the DBGrid
   KeyField  := 'id';
   ListField := 'resource_name; id';

   Visible    := False;
 end;

 DataSource2.DataSet := AdoQuery1;

 AdoQuery1.Connection := AdoConnection1;
 AdoQuery1.SQL.Text := 'SELECT id,resource_name FROM resources';
 AdoQuery1.Open;
end;

1 个答案:

答案 0 :(得分:1)

以下是使用来自François的整洁黑客的一种解决方案。

type
    // Hack to redeclare your TDBGrid here without the the form designer going mad
    TDBGrid = class(DBGrids.TDBGrid)
      procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
    end;

  TForm1 = class(TForm)
[...]
procedure TDBGrid.WMHScroll(var Msg: TWMHScroll);
begin
  if Form1.DBGrid1.SelectedField.FieldName = Form1.DBLookupComboBox1.DataField then begin
    case Msg.ScrollCode of
      SB_LEFT,SB_LINELEFT,SB_PAGELEFT: begin
        Form1.DBGrid1.SelectedIndex := Form1.DBGrid1.SelectedIndex-1;
        Form1.DBLookupComboBox1.Visible := False;
      end;
      SB_RIGHT,SB_LINERIGHT,SB_PAGERIGHT: begin
        Form1.DBGrid1.SelectedIndex := Form1.DBGrid1.SelectedIndex+1;
        Form1.DBLookupComboBox1.Visible := False;
      end;
    end;
  end;
  inherited; // to keep the expected behavior
end;