Author: Tomas Rutkauskas
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.
1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 StdCtrls,
8 Grids;
9
10 type
11 TForm1 = class(TForm)
12 StringGrid1: TStringGrid;
13 ComboBox1: TComboBox;
14 procedure ComboBox1Exit(Sender: TObject);
15 procedure FormCreate(Sender: TObject);
16 procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var
17 CanSelect: Boolean);
18 private
19 { Private declarations }
20 procedure CMDialogKey(var msg: TCMDialogKey); message CM_DIALOGKEY;
21 public
22 { Public declarations }
23 end;
24
25 var
26 Form1: TForm1;
27
28 implementation
29
30 {$R *.DFM}
31
32 procedure TForm1.CMDialogKey(var msg: TCMDialogKey);
33 begin
34 if Activecontrol = ComboBox1 then
35 begin
36 if msg.CharCode = VK_TAB then
37 begin
38 {set focus back to the grid and pass the tab key to it}
39 stringgrid1.setfocus;
40 stringgrid1.perform(WM_KEYDOWN, msg.charcode, msg.keydata);
41 {swallow this message}
42 msg.result := 1;
43 Exit;
44 end;
45 end;
46 inherited;
47 end;
48
49 procedure TForm1.ComboBox1Exit(Sender: TObject);
50 begin
51 with sender as TComboBox do
52 begin
53 hide;
54 if itemindex >= 0 then
55 with stringgrid1 do
56 cells[col, row] := items[itemindex];
57 end;
58 end;
59
60 procedure TForm1.FormCreate(Sender: TObject);
61 begin
62 ComboBox1.visible := false;
63 end;
64
65 procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
66 var CanSelect: Boolean);
67 var
68 R: TRect;
69 org: TPoint;
70 begin
71 with Sender as TStringGrid do
72 if (ACol = 2) and (ARow >= FixedRows) then
73 begin
74 {entered the column associated to the combobox}
75 {get grid out of selection mode}
76 perform(WM_CANCELMODE, 0, 0);
77 {position the control on top of the cell}
78 R := CellRect(Acol, Arow);
79 org := Self.ScreenToClient(ClientToScreen(R.topleft));
80 with ComboBox1 do
81 begin
82 setbounds(org.X, org.Y, r.right - r.left, height);
83 itemindex := Items.IndexOf(Cells[acol, arow]);
84 Show;
85 BringTofront;
86 {focus the combobox and drop down the list}
87 SetFocus;
88 DroppedDown := true;
89 end;
90 end;
91 end;
92
93 end.
Solve 2:
94 unit GridCombo;
95
96 interface
97
98 uses
99 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
100 Grids, StdCtrls;
101
102 type
103 TFrmGridCombo = class(TForm)
104 StringGrid1: TStringGrid;
105 BtnSave: TButton;
106 StringGrid2: TStringGrid;
107 BtnLoad: TButton;
108 procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var
109 CanSelect: Boolean);
110 private
111 FCBox: TComboBox;
112 procedure ComboClick(Sender: TObject);
113 public
114 { Public declarations }
115 end;
116
117 var
118 FrmGridCombo: TFrmGridCombo;
119
120 implementation
121
122 {$R *.DFM}
123
124 procedure TFrmGridCombo.StringGrid1SelectCell(Sender: TObject; ACol,
125 ARow: Integer; var CanSelect: Boolean);
126 var
127 thisRect: TRect; {Notational clarity.}
128 begin
129 if (ARow = 1) and (ACol <> 0) then
130 begin
131 if Assigned(FCBox) then
132 FCBox.Free;
133 FCBox := TComboBox.Create(self);
134 FCBox.Parent := self;
135 thisRect := StringGrid1.CellRect(ACol, ARow);
136 FCBox.Left := thisRect.Left + StringGrid1.Left + 2;
137 FCBox.Top := thisRect.Top + StringGrid1.Top + 2;
138 FCBox.Width := (thisRect.Right - thisRect.Left);
139 FCBox.Height := (thisRect.Bottom - thisRect.Top);
140 FCBox.Items.LoadFromFile('File2.Txt');
141 FCBox.SetFocus;
142 FCBox.OnClick := ComboClick;
143 end
144 else if Assigned(FCBox) then
145 begin
146 FCBox.Free;
147 FCBox := nil;
148 end;
149 end;
150
151 procedure TFrmGridCombo.ComboClick(Sender: TObject);
152 begin
153 if Sender is TComboBox then
154 StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] := TComboBox(Sender).Text;
155 end;
156
157 end.
|