Attach a TComboBox to the column of a TStringGrid (Views: 28)
Problem/Question/Abstract: How to attach a TComboBox to the column of a TStringGrid Answer: Solve 1: Here is one way to do it, using a single combobox that moves from cell to cell as required. unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type TForm1 = class(TForm) StringGrid1: TStringGrid; ComboBox1: TComboBox; procedure ComboBox1Exit(Sender: TObject); procedure FormCreate(Sender: TObject); procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); private { Private declarations } procedure CMDialogKey(var msg: TCMDialogKey); message CM_DIALOGKEY; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.CMDialogKey(var msg: TCMDialogKey); begin if Activecontrol = ComboBox1 then begin if msg.CharCode = VK_TAB then begin {set focus back to the grid and pass the tab key to it} stringgrid1.setfocus; stringgrid1.perform(WM_KEYDOWN, msg.charcode, msg.keydata); {swallow this message} msg.result := 1; Exit; end; end; inherited; end; procedure TForm1.ComboBox1Exit(Sender: TObject); begin with sender as TComboBox do begin hide; if itemindex >= 0 then with stringgrid1 do cells[col, row] := items[itemindex]; end; end; procedure TForm1.FormCreate(Sender: TObject); begin ComboBox1.visible := false; end; procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); var R: TRect; org: TPoint; begin with Sender as TStringGrid do if (ACol = 2) and (ARow >= FixedRows) then begin {entered the column associated to the combobox} {get grid out of selection mode} perform(WM_CANCELMODE, 0, 0); {position the control on top of the cell} R := CellRect(Acol, Arow); org := Self.ScreenToClient(ClientToScreen(R.topleft)); with ComboBox1 do begin setbounds(org.X, org.Y, r.right - r.left, height); itemindex := Items.IndexOf(Cells[acol, arow]); Show; BringTofront; {focus the combobox and drop down the list} SetFocus; DroppedDown := true; end; end; end; end. Solve 2: unit GridCombo; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls; type TFrmGridCombo = class(TForm) StringGrid1: TStringGrid; BtnSave: TButton; StringGrid2: TStringGrid; BtnLoad: TButton; procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); private FCBox: TComboBox; procedure ComboClick(Sender: TObject); public { Public declarations } end; var FrmGridCombo: TFrmGridCombo; implementation {$R *.DFM} procedure TFrmGridCombo.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); var thisRect: TRect; {Notational clarity.} begin if (ARow = 1) and (ACol <> 0) then begin if Assigned(FCBox) then FCBox.Free; FCBox := TComboBox.Create(self); FCBox.Parent := self; thisRect := StringGrid1.CellRect(ACol, ARow); FCBox.Left := thisRect.Left + StringGrid1.Left + 2; FCBox.Top := thisRect.Top + StringGrid1.Top + 2; FCBox.Width := (thisRect.Right - thisRect.Left); FCBox.Height := (thisRect.Bottom - thisRect.Top); FCBox.Items.LoadFromFile('File2.Txt'); FCBox.SetFocus; FCBox.OnClick := ComboClick; end else if Assigned(FCBox) then begin FCBox.Free; FCBox := nil; end; end; procedure TFrmGridCombo.ComboClick(Sender: TObject); begin if Sender is TComboBox then StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] := TComboBox(Sender).Text; end; end. |