将DBLookupCombobox添加到Delphi DBGrid
我想向DBGrid中的某些列添加DBLookupComboBox。About.com上有一篇关于如何做到这一点的好文章。问题是,对于具有多个列的表,如果从DBLookupCombobox中选择一列,然后尝试向左滚动,则combobox也将向左移动,如所包含的图像所示。如何更改About.com代码以防止这种行为?一次网络搜索显示,另外两人抱怨完全相同的问题,但没有解决方案。请注意,我想使用DBLookupCombobox来显示名称,但要输入id,因此使用简单的选取列表是不行的将DBLookupCombobox添加到Delphi DBGrid,delphi,dbgrid,Delphi,Dbgrid,我想向DBGrid中的某些列添加DBLookupComboBox。About.com上有一篇关于如何做到这一点的好文章。问题是,对于具有多个列的表,如果从DBLookupCombobox中选择一列,然后尝试向左滚动,则combobox也将向左移动,如所包含的图像所示。如何更改About.com代码以防止这种行为?一次网络搜索显示,另外两人抱怨完全相同的问题,但没有解决方案。请注意,我想使用DBLookupCombobox来显示名称,但要输入id,因此使用简单的选取列表是不行的 这里有一个解决
这里有一个解决方案,它使用了来自
指向About.com代码的链接不够。我们需要你的代码(MCVE)来演示这个问题。很明显,它在大约上与代码一起工作,因为其他人(包括我)使用它时没有问题。也许这是Delphi的问题。我将代码一字不差地粘贴到一个新项目中(我的数据引用除外),并在Delphi XE和Delphi 2006上看到了这种行为。我在Delphi2007中使用的代码没有问题。我看不出你在这里做了什么。如果您需要代码方面的帮助,请在问题中包含代码。链接到其他人的代码是没有好处的,我们不应该离开此站点来了解您的要求。看来使此方法起作用的唯一方法是创建DBGrid子体,然后在TCustomGrid中显示WMHSCROL过程。然后,在滚动过程中,可以使用DBLookupCombobox(或任何其他组件)将焦点移出单元格。希望我错了。
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;
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;