Использование Delphi 10.2 Токио.
Я использую метод DrawCell, чтобы все столбцы в строке имели тот же цвет, что и выбранная ячейка. Это позволяет мне разрешить пользователю щелкать по разным ячейкам, но при этом показывать «выбранную» строку.
При этом используется метод OnSelectCell для аннулирования исходной строки и вновь выбранной строки. Пользуюсь этим методом много лет.
Если у меня есть сетка с горизонтальной полосой прокрутки, сетка не отображается должным образом при прокрутке вправо, и пользователь щелкает ячейку.
Вот простой пример использования TDrawGrid с событиями OnDrawCell и OnSelectCell:
Код формы (DFM):
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 299
ClientWidth = 635
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object DrawGrid1: TDrawGrid
Left = 0
Top = 0
Width = 635
Height = 299
Align = alClient
Color = clWhite
ColCount = 15
DefaultColWidth = 65
DefaultRowHeight = 48
DefaultDrawing = False
DrawingStyle = gdsGradient
RowCount = 12
GradientEndColor = clBtnFace
GradientStartColor = clBtnFace
Options = [goThumbTracking]
ParentShowHint = False
ShowHint = True
TabOrder = 0
OnDrawCell = DrawGrid1DrawCell
OnSelectCell = DrawGrid1SelectCell
ColWidths = (
65
65
65
65
65
65
65
65
65
65
65
65
65
65
65)
RowHeights = (
48
48
48
48
48
48
48
48
48
48
48
48)
end
end
Код устройства (PAS):
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Math;
type
TGridCracker = class(TDrawGrid)// required to access protected method Invalidaterow - info gleaned from Team B member Peter Below on the Internet
private
public
end;
TForm1 = class(TForm)
DrawGrid1: TDrawGrid;
procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
procedure DrawGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
var MyCanvas : TCanvas;
str : string;
MyRect : TRect;
begin
MyCanvas := TDrawGrid(Sender).Canvas;
MyCanvas.Font.Name := 'Arial'; // drawgrid uses Tahoma 8pt as its default font, not Arial
MyCanvas.Font.Size := 9;
MyCanvas.Brush.Color := TDrawGrid(Sender).FixedColor;
MyCanvas.Font.Color := TDrawGrid(Sender).Font.Color;
MyCanvas.FillRect(Rect);
if (ARow = 0) then begin
str := EmptyStr;
if (ACol > 0) then begin
str := ACol.ToString;
end
else begin
str := 'TEST';
end;
MyCanvas.Font.Color := clblack; // clGray;
MyRect.Left := Rect.Left + 1;
MyRect.Top := Rect.Top + 3;
MyRect.Right := Rect.Right - 1;
MyRect.Bottom := Rect.Bottom - 3;
MyCanvas.FillRect(MyRect);
MyCanvas.Brush.Color := clGray;
MyCanvas.FrameRect(MyRect);
MyCanvas.Brush.Color := clWhite;
MyCanvas.Font.Style := MyCanvas.Font.Style + [fsBold];
MyRect.Top := MyRect.Top + 2;
DrawText(MyCanvas.Handle, pChar(str), -1, MyRect, DT_VCENTER or DT_CENTER);
MyCanvas.Font.Style := MyCanvas.Font.Style - [fsBold];
end
else begin
if (ACol = 0) then begin
MyCanvas.Brush.Color := clMaroon;
MyCanvas.FillRect(Rect);
end
else begin//ACol > 0
if ARow = DrawGrid1.Row then begin
MyCanvas.Brush.Color := clBlue;
end
else begin
MyCanvas.Brush.Color := clwhite;
end;
MyCanvas.FillRect(Rect);
// other cell drawing of text happens after here
end;
end;
end;
procedure TForm1.DrawGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
TGridCracker(Sender).InvalidateRow(TGridCracker(Sender).Row);
TGridCracker(Sender).InvalidateRow(ARow);
end;
end.
Запустите программу.
Щелкните горизонтальную полосу прокрутки, чтобы стал виден столбец 14.
Нажмите на столбец 13 в строке 2.
Нажмите на столбец 12 в строке 3.
Заметили действительно запутанный шаблон выбора?
Вот скриншот результата:
В идеале должен быть один ряд синих ячеек, а не беспорядочный беспорядок. Ряд 3 должен быть сплошным синим цветом.
Вызов DrawGrid1.Refresh в методе OnSelectCell даже не исправляет ситуацию.
Любые идеи о том, как заставить это действительно работать? Я не могу использовать RowSelect для этой сетки.
Ваше здоровье!
TJ