7

I need to change the text color in a cell of TStringGrid in Delphi.

Just a cell. How can I do that?

bluish
  • 26,356
  • 27
  • 122
  • 180
user980115
  • 83
  • 1
  • 1
  • 5

1 Answers1

14

You could use the DrawCell event to draw the cell content yourself.

procedure TForm1.GridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  S: string;
  RectForText: TRect;
begin
  // Check for your cell here (in this case the cell in column 4 and row 2 will be colored)
  if (ACol = 4) and (ARow = 2) then
  begin
    S := Grid.Cells[ACol, ARow];
    // Fill rectangle with colour
    Grid.Canvas.Brush.Color := clBlack;
    Grid.Canvas.FillRect(Rect);
    // Next, draw the text in the rectangle
    Grid.Canvas.Font.Color := clWhite;
    RectForText := Rect;
    // Make the rectangle where the text will be displayed a bit smaller than the cell
    // so the text is not "glued" to the grid lines
    InflateRect(RectForText, -2, -2);
    // Edit: using TextRect instead of TextOut to prevent overflowing of text
    Grid.Canvas.TextRect(RectForText, S);
  end;
end;

(Inspired by this.)

Heinrich Ulbricht
  • 10,064
  • 4
  • 54
  • 85
  • +1. In addition to your edit based on Remy's comment: Since the question asked about a specific *cell*, you should probably show how to change only one cell by using the `ACol` and `ARow` parameters (and maybe explain the call to `InflateRect` - as a suggestion, though, you don't need a separate var; you can directly pass `Rect` to `InflateRect`, since it's not declared as a `const`). – Ken White Nov 07 '11 at 23:12
  • 2
    @Ken I added some more explanations and the cell check. Initially I was tempted to give "use another component providing more formatting features" as the real answer as I find custom drawing always a bit dangerous because it might destroy the native look and feel. It is probably better to draw all cells custom than to risk that the other cells somehow look differently. And regarding the Rect: I am cautious. Maybe somebody decides to add code to the end of the method using Rect, unaware of the change I made to the values. – Heinrich Ulbricht Nov 07 '11 at 23:23
  • Heinrich, the asker should know when changing it that they're modifying the `Rect`. If someone else is changing it, they should be reading the existing code before doing so. :) Nice edits - it makes the answer more self-explanatory to someone new to Delphi that finds this answer in a search. Re: cell color, you can handle drawing the default look by checking for fixed rows and cols and skipping them, using `clWindow` and `clWindowText` (or `clHighlight` and `clHighlightText` depending on `State`), and basically by calling only `InflateRect` and `TextRect` if the cell is NOT to be drawn. – Ken White Nov 07 '11 at 23:30
  • Ah well. If in a rush things are possible one wouldn't believe ;) – Heinrich Ulbricht Nov 07 '11 at 23:35
  • @Ken What about theming? Do we have to care about this? – Heinrich Ulbricht Nov 07 '11 at 23:40
  • Not unless you're trying to draw your own fixed rows or columns. :) That's why I suggested using the `clWindow` and `clWindowText` system colors; changes in theme colors should be handled for you, and the default drawing without changing anything should handle the rest. I have a full example of drawing a `TStringGrid` with a right-aligned column for monetary values I use at work that responds to theming just fine, and it's a dozen lines of code or so. Wasn't suggesting custom-drawing your own grid all the time; if you need that, a custom component is better. – Ken White Nov 08 '11 at 00:14
  • I tend to use DrawText instead of TextRect/TextOut because you can control Vertical and Horizontal Alignment useful for numbers for example – Daniel Luyo Nov 08 '11 at 01:56