0

Learning Delphi (have a ways to go), using Rio.

I figured out how to use a colored background in TStringGrid rows - but it looks like I need to refresh when data in those rows changes (so as to get different colors to show up based on the data changes).

I thought that just setting the cell values to their then-existing values would cause the refresh. But it didn't. I could tell for sure that it didn't - because I had a debug breakpoint placed within the StringGrid1DrawCell procedure - and that breakpoint was not hit.

The code that I had been using to hopefully cause the refresh in TStringGrid was as follows (note: S is defined as a String):

S := StringGrid1.Cells[1, i];
StringGrid1.Cells[1, i] := S;

Is the basic assumption (that just setting/resetting values of the cell contents causes a refresh) in error?

If the idea is right, but the method is wrong: could you let me know what to do differently?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

1 Answers1

3

The OnDrawCell event is fired only when a given cell needs to be painted onscreen.

Setting a specific cell's value will invalidate only that cell, thus triggering a repaint of only that cell, not the cell's entire row, or the grid as a whole.

If you need to trigger a repaint of an entire row, call the grid's (protected) InvalidateRow() method, eg:

type
  TStringGridAccess = class(TStringGrid)
  end;

procedure TMyForm.DoSomething;
begin
  ... 
  StringGrid1.Cells[1, i] := ...; 
  TStringGridAccess(StringGrid1).InvalidateRow(i);
  ...
end;

If you need to trigger a repaint of the entire grid, call the grid's (public) Invalidate() method, eg:

StringGrid1.Cells[1, i] := ...;
StringGrid1.Invalidate;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks for this assistance! But, when I tried it, I learned that I don't have access to Invalidate. I noted that one of your suggestions included TStringGridAccess... but looks like I need to declare TStringGridAccess in some form. Did a search on that, but haven't figured that part out, yet. Again, thank you! – user2372039 Feb 18 '23 at 14:31
  • @user2372039 "*I don't have access to Invalidate*" - Yes, you do, as it is a **public** method of `TWinControl`, which `TStringGrid` derives from. Or, do you mean `InvalidateRow()` instead? If so: "*looks like I need to declare TStringGridAccess in some form*" - yes, you would need to add it to your own code, *exactly* as I have shown it. `InvalidateRow()` is a **protected** method, so only a derived class can reach it. The technique I have shown is very common in Delphi programming, it is known as an **access(or) class**, see https://stackoverflow.com/questions/18067430/. – Remy Lebeau Feb 18 '23 at 19:30
  • Apologies, but I tried exactly what you have put in the comment for the code... in one case, I got the message about lack of Declaration - and in the other (the one where you have the word Access as part of the suggestion), I got a type of Access error. I will keep reading, though. – user2372039 Feb 18 '23 at 23:24
  • @user2372039 then you are not applying it to your code correctly. See if the edit I just made to the example in my answer helps you. – Remy Lebeau Feb 19 '23 at 01:26