Reputation: 486
I have a dbGrid filled by a MyDAC-SQL-Query set to RowSelect. One column contains a location string and there can be multiple rows for each location.
What i want to do is to give a visual feedback to better distinguish between different locations. So the rows with the first location should have a white background and the second a grey one, the third a white, and so on...
I know how to give every second row a different background, but i'm struggeling to detect on which row the location changes.
So, in the DrawColumnCell
procedure i would like to look at the location value of the previous row to detect the change. How can i achieve that?
Upvotes: 2
Views: 2017
Reputation: 125708
You have to implement some logic to store the previous field's value, and to determine whether or not a new color is necessary.
Here's a quick example of doing so. To set it up, just a few steps are needed - I've started with a new, blank VCL forms application for simplicity.
Add three new variables to the form's private
section:
private
SameCity, SameColor: Boolean;
LastCity: string;
Add the following code to the form's OnCreate
event to set up the data and initialize the variables:
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
// One field dataset, with the exact same cities and rows
// you've shown in your question
CDS.FieldDefs.Add('City', ftString, 10);
CDS.CreateDataSet;
for I := 1 to 3 do
CDS.AppendRecord(['London']);
for i := 1 to 2 do
CDS.AppendRecord(['Paris']);
CDS.AppendRecord(['Berlin']);
for i := 1 to 2 do
CDS.AppendRecord(['New York']);
CDS.Open;
// Initialize variables for first use
LastCity := '';
SameColor := False;
SameCity := False;
end;
Add an event handler to the DBGrid for the OnDrawDataCell
event, with the following code:
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
const
RowColors: array[Boolean] of TColor = (clWindow, clLtGray);
begin
// See if we're on the same city as the last row, and save the
// value in the current row for use next row.
SameCity := (Field.AsString = LastCity);
LastCity := Field.AsString;
// If they weren't the same, toggle the color value
if not SameCity then
SameColor := not SameColor;
// Set the row color and tell the grid to draw the row
(Sender as TDBGrid).Canvas.Brush.Color := RowColors[SameColor];
(Sender as TDBGrid).DefaultDrawDataCell(Rect, Field, State);
end;
I've used OnDrawDataCell instead of OnDrawColumnCell because it doesn't get called on the header row or fixed column, so the DBGrid will take care of drawing those completely.
Running the application produces these results.
Upvotes: 2