Установка цвета фона выбранной строки в TStringGrid
У меня есть TStringGrid, где выбранная строка (макс. 1, без множественного выбора) всегда должна иметь разный фон colo(u)r.
Я установил для свойства DefaultDrawing значение false и предоставил метод для события OnDrawCell, показанного ниже, - но он не работает. Я даже не могу точно описать, как это не работает; Я полагаю, что если бы я мог, я бы уже решил проблему. Достаточно сказать, что вместо полных рядов с одним и тем же цветом фона это мешанина. Несколько строк имеют несколько ячеек "выбранного" цвета, и не все ячейки выбранной строки имеют выбранный цвет.
Обратите внимание, что я сравниваю строку ячейки со строкой strnggrid; Я не могу проверить состояние ячейки для выбранного, так как выбрана только ячейка выбранной строки.
procedure TForm1.DatabaseNamesStringGridDrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
var cellText :String;
begin
if gdFixed in State then
DatabaseNamesStringGrid.Canvas.Brush.Color := clBtnFace
else
if ARow = DatabaseNamesStringGrid.Row then
DatabaseNamesStringGrid.Canvas.Brush.Color := clAqua
else
DatabaseNamesStringGrid.Canvas.Brush.Color := clWhite;
DatabaseNamesStringGrid.Canvas.FillRect(Rect);
cellText := DatabaseNamesStringGrid.Cells[ACol, ARow];
DatabaseNamesStringGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, cellText);
end;
4 ответа
Если вы пытаетесь закрасить выбранную строку или ячейку другим цветом, вы должны проверить gdSelected
значение в state
вар.
procedure TForm1.DatabaseNamesStringGridDrawCell(Sender: TObject;
ACol, ARow: Integer;
Rect: TRect;
State: TGridDrawState);
var
AGrid : TStringGrid;
begin
AGrid:=TStringGrid(Sender);
if gdFixed in State then //if is fixed use the clBtnFace color
AGrid.Canvas.Brush.Color := clBtnFace
else
if gdSelected in State then //if is selected use the clAqua color
AGrid.Canvas.Brush.Color := clAqua
else
AGrid.Canvas.Brush.Color := clWindow;
AGrid.Canvas.FillRect(Rect);
AGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, AGrid.Cells[ACol, ARow]);
end;
У вас включены темы во время выполнения? Темы времени выполнения переопределяют любую цветовую схему, которую вы пытаетесь применить для Windows Vista и выше.
Это работает для меня
procedure TFmain.yourStringGrid(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
var
md: integer;
begin
with yourStringGrid do
begin
if yourStringGrid,Row = ARow then
Canvas.Brush.Color:= clYellow //your highlighted color
else begin
md := Arow mod 2;
if md <> 0 then Canvas.Brush.Color:= $00BADCC1 else //your alternate color
Canvas.Brush.Color:= clwhite;
end;
Canvas.FillRect(Rect);
Canvas.TextOut(L, Rect.top + 4, cells[ACol, ARow]);
end;
end;
Обновить сетку
procedure TFmain.yourStringGridClick(Sender: TObject);
begin
yourStringGrid.Refresh;
end;
Примечание: имеет небольшую задержку, но в остальном прекрасно работает.
(Используется в Delphi XE2)
Когда новая ячейка выбрана в сетке строк, только предыдущая и новая выбранная ячейка становятся недействительными. Таким образом, оставшиеся ячейки предыдущего и нового ряда не перерисовываются, давая эффект, который вы описываете.
Одним из обходных путей может быть вызов InvalidateRow для обеих затронутых строк, но это защищенный метод, и вам нужно найти способ доступа к этому методу из обработчика события OnSelectCell. В зависимости от вашей версии Delphi, есть разные способы сделать это.
Самым чистым способом будет наследование от TStringGrid, но в большинстве случаев это невозможно. В более новой версии Delphi вы можете использовать помощника по классам для достижения этой цели. В противном случае вы должны положиться на обычный защищенный взломать.