Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Color String Grid rows based on condition 1

Status
Not open for further replies.

lespaul

Programmer
Feb 4, 2002
7,083
US
I have a string grid on my main form that allows users to see jury trials that are currently going on. Unfortunately sometimes the clerks who are suppose to end the trials don't do it (imagine that!!). So what I'd like to do is check to see how long ago the trial started and if it's more than a specific amount of time, then color that row yellow or red depending on how long ago the trial started.

So I have:
Trial Watcher (* indicates continued)
Case Number Judge Started PanelID Jury
DV240303 1 8/22/03 030818P06 Y
DV275803 3 9/08/03 030902P06 Y
DW125503* 8 9/08/03 030902P02 N

Since the first case is more than 1 days old and has not been continued, I would like this row to be red.
The second case is equal to 1 day old and has not been continued, so it should be yellow. The third case is also equal to 1 day old, but has been continued so it should be the default color as well as any trials that start today.

Any idea on how I can control this type of coloring scheme?

Thanks,

Leslie




Leslie
landrews@metrocourt.state.nm.us

There are 10 types of people in the world -
those who understand binary
and
those who don't!
 
something like this maybe (the hardcode "4" in the if statement is meant to represent the relevant date column):

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
With Sender as TStringGrid do
begin
if Now - StrToDate(Cells[4,Arow]) > 30 then
begin
//for BackGround Color
Canvas.Brush.Color := clRed;
Canvas.FillRect(Rect);
//for Font.Color
Canvas.Font.Color := clGreen;
Canvas.TextRect( Rect, Rect.Left+2, Rect.Top+2, Cells[acol, arow]);
end;
end;
end;

Brian
"There are 2 kinds of people in the world, those that divide people into two groups and those that don't. I belong to the second group." - tag line I stole
 
You rock Brian! have a star!

I modified it a little bit, I had to check for / in the string (since 'Started' isn't a valid date!), I had to use Today instead of Now, and I added the two colors, but that worked like a charm.

Thanks,

leslie

 
Great, I have used similar to colour rows in a String Grid but when there is a scroll bar on the Grid the Text put into Cells not visible does not get added. I am guessing I need to add something to the scroll event handler to redraw the text in the Cells newly visible? DOes that sound right anyone?

 
I don't have to do that, if there is a scroll bar then when I scroll down the colored lines are already there.

Leslie

Anything worth doing is a lot more difficult than it's worth - Unknown Induhvidual
 
EDCAMD:
Were you letting the string grid paint itself? (i.e using the call to ondrawcell in the object inspector) or were you handling the drawing yourself, somtimes a stringgrid wont repaint auotomatically, you can call ondrawcell specificaly, but scrolling should trigger the ondrawcell call automatically.


Steve: Delphi a feersum engin indeed.
 
I am using the StringGridDrawCell to do the Canvas painting. The colouring of the cells works fine all the way through the Grid down into the cells not visible but the TextRect written text does not show up on the non visible cells. I do still have stuff in the FormShow to fill the cells which I plan to remove. I know the TextRect clips text and thought maybe the clipping was the cause so I just need to trigger the repaint when scrolling?
 

EDCAMD, there seems to be a fundamental misunderstanding of how TStringGrid works.

Any string that you put into a cell will be in that cell until it is replaced by something else. It doesn't matter whether the cell is visible or not. A cell might not be visible if the column width is zero, or if the column or row has been scrolled out of view.

The DrawCell event is fired every time Delphi needs to paint the contents of a cell on the screen. You do not need to trigger anything. Delphi does that automatically.

What you do with the DrawCell event is up to you. Most of the time it is ignored and Delphi paints the Canvas with a picture of the contents of the string in the specified font. If however, you wish to have something else appear. (E.g. paint the string in color, or display some graphic) you do that when Delphi asks you to via the DrawCell event.

It is not a one-time thing. If you aren't satisfied with the default Delphi display of the string, you have to paint it yourself every time Delphi fires the Event.

You can't actually change the color of the contents of a cell. It doesn't have a color property. All you can do is paint it "your way" every time you get the event.

When the event fires, use the ARow and ACol parameters of the OnDrawCell event handler to see whether it is time for you to take action.

Hope this helps.

 
In my DrawGrid event handler it paints each cell's canvas by setting the Brush.Color and then using Canvas.FillRect to colour the cell and followed by setting the Font.Color and calling Canvas.TextRect to add text. This works fine for all visible cells but the text isn't painted on the cells not visible thought the cell colour is painted! As seen when I then scroll down.

All the cells are repainted when a different selection is made from a ComboBox listing 20 odd options (in my case staff names as the whole grid displays staff absences over a year).

Are you suggesting the OnDrawCell event handler needs to be aware of which Cells are visible as currently it doesn't it just assumes all need painting and then has condiotnal statement to work our what colour and text need painting on a cell.
 
Not sure how to explain it any more clearly than my previous attempt, but here goes...

The OnDrawCell event handler does not need to know anything about visibility -- that is Delphi's job. The OnDrawCell event handler is told what cell is needing drawing (ACol and ARow parameters) and must then make the necessary decisions as to what to do for that specific cell.

OnDrawCell will only fire for visible cells, by definition. If it's not visible, there is no need (in fact, no way) to draw it, so why would you want to try?
...it just assumes all need painting...
Definitely NOT! There is no assumption here, and you do NOT paint ALL. The event handler is told precisely WHICH cell needs painting and it is up to the handler (your code) to decide whether that cell needs special handling or not.

You need to be absolutely clear on this. Your event handler should either do nothing or else it can draw, but if it draws it must draw only within the TRect specified for the TStringGrid.Canvas.
 
Thaks for your persistance. I understand what you say but it does not explain why when the cells are visiblt the FillRect works but not the TextRect for the same cell. I will double check my logic that works out how a cell is to be painted. It is just that it seems to correctly work out, for exmaple, that a cell must be green for sickness but then fail to add the text 'sick' to that cell when both ststements are in the same code block.

Also I have noticed that when I scroll back sometimes the text is missing for some of the visible cells but not all! I am beginning to think either there is some strange memory issue or a bug in Delphi (I am using v7 personal edition).

Thanks again what you have siad confirms my understanding of how it should work.
 
Can you copy and paste your OnDrawCell code? I suspect that the bug is more likely to be there than in Delphi v7. If the code is lengthy, can you produce a small sample routine that displays the same erroneous behaviour? You may find that by creating a small sample routine that you will find the cause of the problem.

Andrew
Hampshire, UK
 
Further to Andrew's point, it is not a good idea to have lots of code in an ondrawcell, as you normally have no control over when it is called. i.e when the stringgrid is repainted.


Steve: Delphi a feersum engin indeed.
 
I have written a simple single form exmaple and am convinced the problem is related to the scrolling. ANyway here is the DrawCell procedure:

procedure TTestStringGrids.StringGridDrawCell(Sender: TObject; ACol,
ARow: Integer; Rect: TRect; State: TGridDrawState);
var
X, Y : integer;
BkGrdColour : TColor;
TxtString : String;
begin
if (ARow>=0) and (ACol>=0) then
begin
if (ARow>0) and (ARow<11) then
BkGrdColour := $00CCFFCC
else if (ARow>20) then
BkGrdColour := $00CCDDFF
else if (ARow>0) then
BkGrdColour := $00EECCFF
else
BkGrdColour := StringGrid.FixedColor;
if (ARow>0) then
begin
if (ACol=0) then
TxtString := 'ARow: '+Write_No(ARow,3)
else if (ACol=1) then
TxtString := Write_No(Numbers[(ARow+ACol) mod 100],3)
else if (ACol=2) then
TxtString := Write_No(Numbers[(ARow+ACol) mod 100],3)
else if (ACol=3) then
TxtString := Write_No(Numbers[(ARow+ACol) mod 100],3)
else if (ACol=4) then
TxtString := Write_No(Numbers[(ARow+ACol) mod 100],3)
end
else
TxtString := 'ACol: '+Write_No(ACol,1);

X := ACol*(StringGrid.DefaultColWidth+StringGrid.GridLineWidth)+4;
Y := ARow*(StringGrid.DefaultRowHeight+StringGrid.GridLineWidth)+2;
StringGrid.Canvas.Brush.Color := BkGrdColour;
StringGrid.Canvas.FillRect(Rect);
StringGrid.Canvas.Font.Color:= clBlack;
StringGrid.Canvas.TextRect(Rect,X,Y,TxtString);

end
end;


 
It looks like your calculation of the X and Y offsets is the problem.

The final line where you call TextRect can use offsets relative to the actual cell you are processing. For example, I think you are trying to have a horizontal offset of 4 and a vertical offset of 2. It is much easier to code this as
Code:
StringGrid.Canvas.TextRect ( Rect, Rect.Left + 4, Rect.Top + 2, TxString );
Okay, best not to use constants of 4 and 2 but you should get the picture.

This is, of course, much more maintainable because if you have different column widths your own algorithm will have to become much more convoluted.

Andrew
Hampshire, UK
 
The Grid has 101 rows and on first showing it is as expected but you scroll down and there is no text in the rows that were not initially visible but the cells have been coloured as expected. Scroll back up and sometimes you get all the text, others only some of it! I have tried it with DefulatDrawing on and off. I have tried adding Repaint to the OnTopLeftChanged event but nothing helps.

I know my code isn't perfect, after 25 years you learn something, but am struggling on what I am missing. I just think that when I scroll I need to do something else or there's a bug in the VCL?
 

Perhaps your posts crossed, but Andrew has given you the answer. You are misusing the TCanvas.TextRect method.

What is happening is, you are painting text outside of the current cell. As Delphi continues to fire the DrawCell events, you eventually paint over what you have previously painted.

As we all learned in kindergarden, when painting it is best to stay within the lines. [smile]

 
Okay, I understand that BUT that does not explain why Text gets written successfully sometimes when I scroll up quickly but not when slowly. I mean here for a cell where it once displayed successfully it then doesn't show text! Anyway I'll try the alteration becuase it is clearly simply and better than my method, thanks. I'll confirm success shortly.
 
Okay, I have tried changing the code along the lines Andrew (Hamps) suggests and its different. I do now get text in cells when I scroll down but not in all cells. I am guessing the simple Top+4 and Left+4 needs tweaking so I'll look at the definitions for these values and tweak away!

Andy
 
Okay now you can chortle. Now I have got the Left and Top the correct way around it looks good. Thanks everyone, got there in the end. I'll now add the TextHeight/Width adjustments and remove the constants as suggested.

I still say some of the affects caused by the inaccurate X,Y calculations were weird but then many bug side effects are equally weird so I shouldn't be surprised! Shows how little coding I do nowadays :(

Thanks again.

Andy
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top