Author: Mike Shkolnik
How can I use a combobox as inplace editor in standard TStringGrid?
Answer:
I wrote a small app which demonstrates how you can use the some combobox instead
standard inplace editor in TStringGrid component.
Also in this app you can view how change font and/or alignment for some cells.
The form contents as text:
1 object frmMain: TfrmMain
2 Left = 200
3 Top = 108
4 Width = 510
5 Height = 382
6 Caption = 'Example: TStringGrid advanced using'
7 Font.Charset = DEFAULT_CHARSET
8 Font.Color = clWindowText
9 Font.Height = -11
10 Font.Name = 'MS Sans Serif'
11 Font.Style = []
12 OnCreate = FormCreate
13 PixelsPerInch = 96
14 TextHeight = 13
15 object StringGrid1: TStringGrid
16 Left = 24
17 Top = 152
18 Width = 457
19 Height = 161
20 ColCount = 2
21 DefaultColWidth = 200
22 DefaultRowHeight = 21
23 RowCount = 9
24 TabOrder = 0
25 OnDrawCell = StringGrid1DrawCell
26 OnSelectCell = StringGrid1SelectCell
27 ColWidths = (
28 118
29 296)
30 end
31 object cbInplaceComboBox: TComboBox
32 Left = 32
33 Top = 320
34 Width = 145
35 Height = 21
36 Style = csDropDownList
37 ItemHeight = 13
38 Items.Strings = (
39 '1 value'
40 '2 value'
41 '3 value'
42 '4 value'
43 '5 value'
44 '6 value'
45 '7 value'
46 '8 value'
47 '9 value')
48 TabOrder = 1
49 OnChange = cbInplaceComboBoxChange
50 end
51 object btnClose: TButton
52 Left = 416
53 Top = 320
54 Width = 75
55 Height = 25
56 Cancel = True
57 Caption = '&Close'
58 default = True
59 TabOrder = 2
60 OnClick = btnCloseClick
61 end
62 object MemoDescription: TMemo
63 Left = 24
64 Top = 8
65 Width = 457
66 Height = 129
67 Font.Charset = DEFAULT_CHARSET
68 Font.Color = clNavy
69 Font.Height = -11
70 Font.Name = 'MS Sans Serif'
71 Font.Style = [fsBold]
72 Lines.Strings = (
73 'In this sample I shows how you can:'
74 ' '
75 '1. change the inplace editor for second column'
76 ' from standard inplace editor to user TComboBox component'
77 ' '
78 ' view the next procedures:'
79 ' - TfrmMain.FormCreate'
80 ' - TfrmMain.CMDialogKey'
81 ' - TfrmMain.cbInplaceComboBoxChange'
82 ' - TfrmMain.StringGrid1SelectCell'
83 ' '
84 '2. draw the cell values with different fonts'
85 ' '
86 ' view the next procedure:'
87 ' - TfrmMain.StringGrid1DrawCell'
88 ' '
89 '3. change alignment for cells'
90 ' '
91 ' view the next procedure:'
92 ' - TfrmMain.StringGrid1DrawCell')
93 ParentFont = False
94 ScrollBars = ssVertical
95 TabOrder = 3
96 end
97 end
98
99 The pas - file for same form:
100
101 unit Main;
102
103 interface
104
105 uses
106 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
107 StdCtrls, Grids;
108
109 type
110 TfrmMain = class(TForm)
111 StringGrid1: TStringGrid;
112 cbInplaceComboBox: TComboBox;
113 btnClose: TButton;
114 MemoDescription: TMemo;
115 procedure FormCreate(Sender: TObject);
116 procedure cbInplaceComboBoxChange(Sender: TObject);
117 procedure StringGrid1SelectCell(Sender: TObject; Col, Row: Integer;
118 var CanSelect: Boolean);
119 procedure StringGrid1DrawCell(Sender: TObject; Col, Row: Integer;
120 Rect: TRect; State: TGridDrawState);
121 procedure btnCloseClick(Sender: TObject);
122 private
123 { Private declarations }
124 procedure CMDialogKey(var msg: TCMDialogKey); message CM_DIALOGKEY;
125 public
126 { Public declarations }
127 end;
128
129 var
130 frmMain: TfrmMain;
131
132 implementation
133
134 {$R *.DFM}
135
136 procedure TfrmMain.FormCreate(Sender: TObject);
137 var
138 i: Integer;
139 begin
140 StringGrid1.DefaultRowHeight := cbInplaceComboBox.Height;
141 cbInplaceComboBox.Visible := False;
142
143 StringGrid1.Cells[0, 0] := 'Row No';
144 StringGrid1.Cells[1, 0] := 'Values (from Combobox)';
145 for i := 1 to StringGrid1.RowCount - 1 do
146 StringGrid1.Cells[0, i] := IntToStr(i);
147 end;
148
149 procedure TfrmMain.CMDialogKey(var msg: TCMDialogKey);
150 begin
151 if (ActiveControl = cbInplaceComboBox) then
152 begin
153 if (msg.CharCode = VK_TAB) then
154 begin
155 //set focus back to the grid and pass the tab key to it
156 cbInplaceComboBox.SetFocus;
157 cbInplaceComboBox.Perform(WM_KEYDOWN, msg.CharCode, msg.KeyData);
158 // swallow this message
159 msg.result := 1;
160 Exit;
161 end;
162 end;
163
164 inherited;
165 end;
166
167 procedure TfrmMain.cbInplaceComboBoxChange(Sender: TObject);
168 var
169 intRow: Integer;
170 begin
171 inherited;
172
173 {Get the ComboBox selection and place in the grid}
174 with cbInplaceComboBox do
175 begin
176 intRow := StringGrid1.Row;
177 if (StringGrid1.Col = 2) then
178 StringGrid1.Cells[2, intRow] := Items[ItemIndex]
179 else
180 StringGrid1.Cells[StringGrid1.Col, intRow] := Items[ItemIndex];
181 Visible := False;
182 end;
183 StringGrid1.SetFocus;
184 end;
185
186 procedure TfrmMain.StringGrid1SelectCell(Sender: TObject; Col, Row: Integer;
187 var CanSelect: Boolean);
188 var
189 R: TRect;
190 begin
191 if ((Col = 1) and (Row <> 0)) then
192 begin
193 {Size and position the combo box to fit the cell}
194 R := StringGrid1.CellRect(Col, Row);
195 R.Left := R.Left + StringGrid1.Left;
196 R.Right := R.Right + StringGrid1.Left;
197 R.Top := R.Top + StringGrid1.Top;
198 R.Bottom := R.Bottom + StringGrid1.Top;
199
200 {Show the combobox}
201 with cbInplaceComboBox do
202 begin
203 Left := R.Left + 1;
204 Top := R.Top + 1;
205 Width := (R.Right + 1) - R.Left;
206 Height := (R.Bottom + 1) - R.Top;
207
208 ItemIndex := Items.IndexOf(StringGrid1.Cells[Col, Row]);
209 Visible := True;
210 SetFocus;
211 end;
212 end;
213 CanSelect := True;
214 end;
215
216 procedure TfrmMain.StringGrid1DrawCell(Sender: TObject; Col, Row: Integer;
217 Rect: TRect; State: TGridDrawState);
218 const
219 AlignFlags: array[TAlignment] of Integer =
220 (DT_LEFT or DT_VCENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
221 DT_RIGHT or DT_VCENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
222 DT_CENTER or DT_VCENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX);
223 var
224 s: string;
225 begin
226 inherited;
227
228 with Rect do
229 begin
230 Left := Left + 2;
231 Top := Top + 2;
232 Right := Right - 5
233 end;
234
235 s := StringGrid1.Cells[Col, Row];
236
237 if (Row = 0) and (Col < StringGrid1.ColCount) then
238 begin
239 StringGrid1.Canvas.Font.Style := StringGrid1.Canvas.Font.Style + [fsBold];
240 StringGrid1.Canvas.Brush.Color := StringGrid1.FixedColor;
241 StringGrid1.Canvas.FillRect(Rect);
242
243 DrawText(StringGrid1.Canvas.Handle,
244 PChar(s), Length(s),
245 Rect, AlignFlags[taCenter]);
246 end
247 else if (Col = 0) and (Row > 0) and (Row < StringGrid1.RowCount) then
248 begin
249 StringGrid1.Canvas.FillRect(Rect);
250 DrawText(StringGrid1.Canvas.Handle,
251 PChar(s), Length(s),
252 Rect, AlignFlags[taRightJustify]);
253 end;
254 end;
255
256 procedure TfrmMain.btnCloseClick(Sender: TObject);
257 begin
258 Close
259 end;
260
261 end.
Component Download: http://www.geocities.com/mshkolnik/FAQ/strgrid.zip
|