Author: Jonas Bilinkevicius
How to draw checkboxes in a TDBGrid
Answer:
Two procedures follow. The first is called from the OnDrawColumnCell event of any
grid that has visible boolean fields, as so:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
DrawCheckBoxes(Sender, Rect, DataCol, Column, State);
end;
Here's the procedure. Place this in your toolkit or utility unit.
1
2 procedure DrawCheckBoxes(Sender: TObject; const Rect: TRect;
3 DataCol: Integer; Column: TColumn; State: TGridDrawState);
4 var
5 MyRect: TRect;
6 fld: TField;
7 begin
8 with (Sender as TDBGrid) do
9 begin
10 fld := Column.Field;
11 if fld is TBooleanField then
12 begin
13 MyRect.Top := ((Rect.Bottom - Rect.Top - 11) div 2) + Rect.Top;
14 MyRect.Left := ((Rect.Right - Rect.Left - 11) div 2) + Rect.Left;
15 MyRect.Bottom := MyRect.Top + 10;
16 MyRect.Right := MyRect.Left + 10;
17 if gdSelected in State then
18 Canvas.Pen.Color := clWhite
19 else
20 Canvas.Pen.Color := clBlack;
21 Canvas.Polyline([
22 Point(MyRect.Left, MyRect.Top), Point(MyRect.Right, MyRect.Top),
23 Point(MyRect.Right, MyRect.Bottom), Point(MyRect.Left, MyRect.Bottom),
24 Point(MyRect.Left, MyRect.Top)]);
25 if fld.AsBoolean then
26 begin
27 Canvas.MoveTo(MyRect.Left + 2, MyRect.Top + 4);
28 Canvas.LineTo(MyRect.Left + 2, MyRect.Top + 7);
29 Canvas.MoveTo(MyRect.Left + 3, MyRect.Top + 5);
30 Canvas.LineTo(MyRect.Left + 3, MyRect.Top + 8);
31 Canvas.MoveTo(MyRect.Left + 4, MyRect.Top + 6);
32 Canvas.LineTo(MyRect.Left + 4, MyRect.Top + 9);
33 Canvas.MoveTo(MyRect.Left + 5, MyRect.Top + 5);
34 Canvas.LineTo(MyRect.Left + 5, MyRect.Top + 8);
35 Canvas.MoveTo(MyRect.Left + 6, MyRect.Top + 4);
36 Canvas.LineTo(MyRect.Left + 6, MyRect.Top + 7);
37 Canvas.MoveTo(MyRect.Left + 7, MyRect.Top + 3);
38 Canvas.LineTo(MyRect.Left + 7, MyRect.Top + 6);
39 Canvas.MoveTo(MyRect.Left + 8, MyRect.Top + 2);
40 Canvas.LineTo(MyRect.Left + 8, MyRect.Top + 5);
41 end;
42 end;
43 end;
44 end;
There's a little setup involved. Select each visible boolean field in the fields
editor and set the DisplayValues to ' ;'. That's space + semicolon. I like the
DisplayWidth set to 2.
The next procedure is optional/ extra. It's a keystroke handler that will change
the value of the field if the user presses space, T, F, Y, or N.Place it in your
utility unit also and call it from your OnKeyPress event in the grid as so:
45
46 procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
47 begin
48 CheckBoxKeyPress(Sender, Key);
49 end;
50
51 and here's the procedure:
52
53 procedure CheckBoxKeyPress(const Sender: TObject; var Key: Char);
54 var
55 fld: TField;
56 tbl: TDataset;
57 i: integer;
58 begin
59 if UpCase(Key) in ['] then
60 begin
61 with (Sender as TDBGrid) do
62 begin
63 i := SelectedIndex;
64 fld := SelectedField;
65 tbl := fld.DataSet;
66 if fld is TBooleanField then
67 begin
68 if not (tbl.State in [dsEdit, dsInsert]) then
69 tbl.Edit;
70 if Key = ' ' then
71 fld.AsBoolean := not fld.AsBoolean
72 else if (UpCase(Key) = 'T') or (UpCase(Key) = 'Y') then
73 fld.AsBoolean := True
74 else
75 fld.AsBoolean := False;
76 tbl.Post;
77 Key := #0;
78 Inc(i);
79 if i = FieldCount then
80 begin
81 i := 0;
82 tbl.Next;
83 if tbl.EOF then
84 tbl.Append;
85 end;
86 SelectedIndex := i;
87 end;
88 end;
89 end;
90 end;
|