1

I am doing this :

procedure TForm1.BitBtn1Click(Sender: TObject);
 var dtStart: TDateTime;
  I: Integer;
begin
  dtStart := DateTimePicker1.Date;
  for I := 0 to 7 do
    AdvStringGrid1.Cells[I+1, 0] := uppercase(FormatDateTime('DD/MM/YYYY     DDD', dtStart + I));
   end;

Is there a way to colour a column when (example) Sunday (SUN) appears? I would like the SUN column (all the way down) to appear in different color than the rest.

Ken White
  • 123,280
  • 14
  • 225
  • 444
user763539
  • 3,509
  • 6
  • 44
  • 103

2 Answers2

4

You can do this by using the OnDrawCell event (do not set DefaultDraw to False). Here's an example with a regular TStringGrid:

// Sample to populate the cells with the days of the week
procedure TForm1.FormShow(Sender: TObject);
var
  r, c: Integer;
begin
  StringGrid1.ColCount := 8;  // Ignore fixed column and row for this example
  StringGrid1.RowCount := 8;

  for c := 1 to StringGrid1.ColCount - 1 do
    for r := 1 to StringGrid1.RowCount - 1 do
      StringGrid1.Cells[c, r] := FormatSettings.ShortDayNames[c];
end;

// Assign this to the StringGrid's OnDrawCell using the Object Inspector 
// Events tab.
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  CellText: string;
begin
  if (ARow > 0) and (ACol > 0) then
  begin
    CellText := StringGrid1.Cells[ACol, ARow];
    if Pos('Sun', CellText) > 0 then
    begin
      StringGrid1.Canvas.Brush.Color := clRed;
      StringGrid1.Canvas.FillRect(Rect);
    end
    else
      StringGrid1.Canvas.Brush.Color := clWindow;
  end;

  // The '+ 4' is from the VCL; it's hard-coded when themes are enabled. 
  // You should probably check the grid's DrawingStyle to see if it's 
  // gdsThemed, and adjust as needed. I leave that as an exercise for you.
  StringGrid1.Canvas.TextOut(Rect.Left + 4, Rect.Top + 4, CellText);
end;

Sample output of the exact code above:

enter image description here

Here's a second example that outputs just exactly what you want (except I didn't convert the SUN to caps):

procedure TForm1.FormShow(Sender: TObject);
var
  r, c: Integer;
begin
  StringGrid1.DefaultColWidth := 100;
  StringGrid1.ColCount := 8;
  StringGrid1.RowCount := 8;

  for c := 1 to StringGrid1.ColCount - 1 do
    for r := 1 to StringGrid1.RowCount - 1 do
      StringGrid1.Cells[c, r] := FormatDateTime('mm/dd/yyyy ddd', 
                                                Date() + c + r - 1);
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  CellText: string;
begin
  if (ARow > 0) and (ACol > 0) then
  begin
    CellText := StringGrid1.Cells[ACol, ARow];
    if Pos('Sun', CellText) > 0 then
      StringGrid1.Canvas.Brush.Color := clRed
    else
      StringGrid1.Canvas.Brush.Color := clWindow;
    StringGrid1.Canvas.FillRect(Rect);
  end;
  StringGrid1.Canvas.TextOut(Rect.Left + 4, Rect.Top + 4, CellText);
end;

Here's the capture to match the second sample:

enter image description here

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • It does not work in my case. I have the date there as well.Also this colours only active cells. I would like to colour the entire column (including the fixed cell) if in column name exists the word SUN. – user763539 May 10 '12 at 15:41
  • This code of yours also wipes out the contents of my cell clean so I cant see anything ... – user763539 May 10 '12 at 15:55
  • Um, no, it doesn't. :) I'll add a screen capture. It will also color any cell containing the text `Sun` (found by the use of `Pos` in the code above), not just active cells. You DO have to adjust the code to fit your exact needs; what I posted was an example of how to do it, but it's only a starting point. :) – Ken White May 10 '12 at 17:00
  • I have the dates you displayed in the column names (which are fixed cells). This version of yours searches through active cells and does not detect the characters in the column name.Like I said, I would like the program to detect the word SUN in the column name and color that column from top to bottom. I am not filling the active cells with dates. However,to me , the first code sample filled a cell with colour and wiped my text out. Will test this new version later but by the look of it it is basically the same as the first version... – user763539 May 10 '12 at 21:14
  • 1
    I think we have a failure to communicate here. :) You asked about coloring a column, which is what I demonstrated. Now you seem to be asking about coloring a *column heading*, which is similar (just remove the check for `Col > 0 and Row > 0`, which removes the fixed cells, and adjust the code accordingly; change the `Pos` to just check what's in the fixed row or column you want to test for `SUN`). Do you want to color the cells in the entire column, or just the column heading? Can you clarify which it is? Thanks. :) – Ken White May 10 '12 at 21:38
  • "cells in the entire column, or just the column heading?" can you display me both versions ? – user763539 May 13 '12 at 07:54
0

Using the DrawCell procedure is the way to go. This example handles the possibility that the column with "Sun" might be in any column. Leave DefaultDrawing to the default - true.


    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
         Rect: TRect; State: TGridDrawState);
    begin
      with Sender as TStringGrid do
       if Pos('Sun', Cells[ACol, 0])>0 then begin
         Canvas.Brush.Color := clRed;
         Canvas.FillRect(Rect);
         Canvas.Font.Color := clwhite;
         Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, Cells[ACol, ARow]);
       end;
      end;
    
bobonwhidbey
  • 485
  • 7
  • 17
  • Sorry for late reply ...I was out a couple of days. I have very odd behaviour of the string grid when I use your code. My column header name which is in 2 rows suddenly becomes one and the part that was in the second row is partly cut off. Also entire column is not colored only when I click on the cell underneath it. I don't know how to post pics here so I could show it to you... – user763539 May 13 '12 at 07:52
  • How do you post pics here ? I dont have that option except in my original question ... 'help' is no help at all ... – user763539 May 13 '12 at 08:00
  • My bad - I didn't realize you were using a 3rd party component. I think with AdvStringGrid you can set the color very easily. You don't need to use a DrawCell procedure.Can't help with pics :( – bobonwhidbey May 13 '12 at 16:04
  • These string grids are supposed to be easy but when you try and do some simple things it turns out to be a nightmare... :-) – user763539 May 13 '12 at 17:20