Problem: we want to color a cell inside a TStringGrid. No easy direct way in doing this in Delphi.
Solution: we must implement stringgrid’s onDrawCell event
Create a new VCL application project. Put one TButton named btnColor and one TStringGrid named strngrd1. See the screenshot below for the placement:
This is the complete Unit1.dfm source code (so you can match the options for each components in the form):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 205 ClientWidth = 280 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object strngrd1: TStringGrid Left = 8 Top = 32 Width = 257 Height = 153 Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goEditing] TabOrder = 0 OnDrawCell = strngrd1DrawCell end object btnColor: TButton Left = 88 Top = 1 Width = 105 Height = 25 Caption = 'Color the Cell' TabOrder = 1 OnClick = btnColorClick end end |
Full form source code below (Unit1.pas):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type TForm1 = class(TForm) strngrd1: TStringGrid; btnColor: TButton; procedure strngrd1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure btnColorClick(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } selectedCol, selectedRow: Integer; colorCell: Boolean; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.btnColorClick(Sender: TObject); begin selectedCol:=1; selectedRow:=1; colorCell:=True; strngrd1.Repaint; end; procedure TForm1.FormCreate(Sender: TObject); begin colorCell:=False; end; procedure TForm1.strngrd1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin if colorCell then begin if ((ACol=selectedCol) and (ARow=selectedRow)) then begin strngrd1.Canvas.Brush.Color:=RGB(255,0,0); //red brush strngrd1.Canvas.FillRect(Rect); //paint the backgorund red //draw the original text strngrd1.Canvas.TextRect(Rect, Rect.Left, Rect.Top, strngrd1.Cells[ACol, ARow]); //draw focused rectangle if the current cell is selected by user if gdFocused in State then strngrd1.Canvas.DrawFocusRect(Rect); end; end; end; end. |
Explanations:
This is our form result:
That’s it. Now you know the concept behind coloring a cell in TStringGrid. If you want to color multiple cell and maintain the status (colored or not and in what color), I suggest you create some TList record variable to store this and onDrawCell will iterate through this list.