Wenn man einmal auf den Canvas malt, dann ist das nur flüchtig (Ausnahme: Bitmaps). D.h. Du musst immer dann, wenn das Grid neu gezeichnet wird, die entsprechenden Zellen gemäß der gewünschten Logik zeichnen.
Daher solltest Du das OnDrawCell-Event belassen und Dir stattdessen merken, was die letzte doppelt geklickte Zeile war. Die malst Du dann grün, die anderen eben weiß.
Um auch den Selektionsrahmen wegzubekommen ist es das einfachste, die Eigenschaft "Defaultdrawing" des Grids auszuschalten.
So funktioniert es dann:
Delphi-Quellcode:
var
GridColorCell: boolean = false;
ClickedRow: Integer = -1;
//StringGrid1.defaultdrawing im Objectinspector auf false setzen
procedure TForm10.StringGrid1DblClick(Sender: TObject);
begin
ClickedRow := -1;
StringGrid1.OnDrawCell := StringGrid1DrawCell;
GridColorCell := true;
StringGrid1.Repaint;
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
//Form10.StringGrid1.OnDrawCell := nil;
end;
procedure TForm10.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var i: Integer;
begin
if GridColorCell then
begin
if ClickedRow = -1 then begin
ClickedRow := Stringgrid1.row;
end;
If ClickedRow = ARow then begin
StringGrid1.Canvas.Brush.Color:=clGreen;
with StringGrid1 do
begin
for i := (ColCount-5) to (ColCount) do
begin
Canvas.FillRect(Rect);
Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+5, Cells[ACol, ClickedRow]);
end;
end;
end else begin
StringGrid1.Canvas.Brush.Color:=clWhite;
stringGrid1.Canvas.FillRect(Rect);
StringGrid1.Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+5, Cells[ACol, ARow]);
end;
end;
end;
Übrigens solltest Du vermeiden, in dem Event direkt die Variable Stringgrid1 zu verwenden, da der Code sonst nicht mehr verwendbar ist, wenn Du z.B. auch andere Stringgrids in der Form so malen wolltest.
Besser wäre daher:
Delphi-Quellcode:
var
sg: TStringGrind;
begin
sg := TStringGrid (Sender);
with sg do begin
....
end;