Установка цвета фона выбранной строки в 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 вы можете использовать помощника по классам для достижения этой цели. В противном случае вы должны положиться на обычный защищенный взломать.

Другие вопросы по тегам