Home » Tipps & Tricks » Komponenten » TStringGrid » Combobox in ein StringGrid einbauen
Combobox in ein StringGrid einbauen
Will man in einer Zelle eines Stringgrids nur bestimmte Werte zulassen, die aus einer Combobox ausgewählt werden sollen, ist etwas Arbeit notwendig. Auf Form1 wird ein normales StringGrid gesetzt. Auf dieses StringGrid kommt eine normale ComboBox, die die zulässigen Werte enthält. Die Combobox wird bei Programmstart unsichtbar gemacht. Erst, wenn der Anwender in die betroffene Spalte des StringGrids kommt, wird sie sichtbar und über der aktiven Zelle eingeblendet. Bei Verlassen der Zelle, wird sie wieder unsichtbar gemacht. Im Beispiel werden alle Zellen der dritten Spalte mit einer Combobox versehen (Methode StringGrid1SelectCell: if (ACol=2)…).
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 procedure CMDialogKey(var msg: TCMDialogKey); message CM_DIALOGKEY; public 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 // setzt den Fokus zurück auf das StringGrid StringGrid1.SetFocus; StringGrid1.Perform(WM_KEYDOWN, msg.CharCode, msg.KeyData); 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.Parent := Stringgrid1; ComboBox1.Visible := False; end; procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); var R: TRect; org: TPoint; begin if (ACol = 2) and (ARow >= StringGrid1.FixedRows) then begin StringGrid1.Perform(WM_CANCELMODE, 0, 0); R := StringGrid1.CellRect(ACol, ARow); org := self.ScreenToClient(self.ClientToScreen(R.TopLeft)); with ComboBox1 do begin SetBounds(org.X, org.Y, R.Right-R.Left, Stringgrid1.Height); ItemIndex := Items.IndexOf(StringGrid1.Cells[ACol, ARow]); Show; BringToFront; SetFocus; DroppedDown := true; end; end; end; end.