logo logo

Color Cell in a stringgrid

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:

delphi color cell in a stringgrid form design

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:

  1. We have declared 3 public variables for this form i.e. selectedRow, selectedCol, colorCell. selectedRow and selectedCol are used for application to decide which cell that will be colored. colorCell is just a controller variable that will decide whether the stringgrid cell will be colored or not.
  2. In Form1 FormCreate event, we set colorCell to False, so, when the form is created an shown, the cell will not be colored.
  3. In btnColor onClick event, we select cell in row 1 and column 1 that will be colored. We also set the colorCell variable to True so the application know what he must done. Next we call Repaint method of strngrd1 so all cells will be re-drawn.
  4. in strngrd1 onDrawCell event, we check whether we should color the cell or not. Then check if the will-be-drawn cell is the same as stated in selectedCol and selectedRow. If True, then we defined to use red brush and then color the cell background with it using FillRect method. Then we also re-draw the text written in there (if any) using TextRect. Lastly, we draw focus rectangle (DrawFocusRect)  only if the current cell is selected by user.

This is our form result:

Our delphi color cell in stringgrid 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.

bottom

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

bottom