How to draw checkboxes in a TDBGrid (Views: 29)
Problem/Question/Abstract: 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. procedure DrawCheckBoxes(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); var MyRect: TRect; fld: TField; begin with (Sender as TDBGrid) do begin fld := Column.Field; if fld is TBooleanField then begin MyRect.Top := ((Rect.Bottom - Rect.Top - 11) div 2) + Rect.Top; MyRect.Left := ((Rect.Right - Rect.Left - 11) div 2) + Rect.Left; MyRect.Bottom := MyRect.Top + 10; MyRect.Right := MyRect.Left + 10; if gdSelected in State then Canvas.Pen.Color := clWhite else Canvas.Pen.Color := clBlack; Canvas.Polyline([ Point(MyRect.Left, MyRect.Top), Point(MyRect.Right, MyRect.Top), Point(MyRect.Right, MyRect.Bottom), Point(MyRect.Left, MyRect.Bottom), Point(MyRect.Left, MyRect.Top)]); if fld.AsBoolean then begin Canvas.MoveTo(MyRect.Left + 2, MyRect.Top + 4); Canvas.LineTo(MyRect.Left + 2, MyRect.Top + 7); Canvas.MoveTo(MyRect.Left + 3, MyRect.Top + 5); Canvas.LineTo(MyRect.Left + 3, MyRect.Top + 8); Canvas.MoveTo(MyRect.Left + 4, MyRect.Top + 6); Canvas.LineTo(MyRect.Left + 4, MyRect.Top + 9); Canvas.MoveTo(MyRect.Left + 5, MyRect.Top + 5); Canvas.LineTo(MyRect.Left + 5, MyRect.Top + 8); Canvas.MoveTo(MyRect.Left + 6, MyRect.Top + 4); Canvas.LineTo(MyRect.Left + 6, MyRect.Top + 7); Canvas.MoveTo(MyRect.Left + 7, MyRect.Top + 3); Canvas.LineTo(MyRect.Left + 7, MyRect.Top + 6); Canvas.MoveTo(MyRect.Left + 8, MyRect.Top + 2); Canvas.LineTo(MyRect.Left + 8, MyRect.Top + 5); end; end; end; 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: procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); begin CheckBoxKeyPress(Sender, Key); end; And here's the procedure: procedure CheckBoxKeyPress(const Sender: TObject; var Key: Char); var fld: TField; tbl: TDataset; i: integer; begin if UpCase(Key) in [' ', 'T', 'F', 'Y', 'N'] then begin with (Sender as TDBGrid) do begin i := SelectedIndex; fld := SelectedField; tbl := fld.DataSet; if fld is TBooleanField then begin if not (tbl.State in [dsEdit, dsInsert]) then tbl.Edit; if Key = ' ' then fld.AsBoolean := not fld.AsBoolean else if (UpCase(Key) = 'T') or (UpCase(Key) = 'Y') then fld.AsBoolean := True else fld.AsBoolean := False; tbl.Post; Key := #0; Inc(i); if i = FieldCount then begin i := 0; tbl.Next; if tbl.EOF then tbl.Append; end; SelectedIndex := i; end; end; end; end; |