Как правильно сделать рисование владельцем выбранной полной строки TDBGrid, если TDBGrid.DefaultDrawing имеет значение false?
Когда у вас есть TDBGrid, выделение полной строки, и вы всегда показываете выделение, даже когда не сфокусировано, и вы хотите полностью нарисовать его владельцем, у вас есть выбор устаревшего события OnDrawDataCell
и новое событие DrawColumnCell
Я выбрал последнее и попробую это:
procedure TDbGridTestForm.mygridDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if gdSelected in State then begin
// mygrid.DrawCellHighlight(Rect, State, Col, Row);
mygrid.Canvas.Brush.Color := clHighlight;
mygrid.Canvas.Font.Color := clHighlightText;
mygrid.Canvas.FillRect(Rect);
end;
mygrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
И что сводит меня с ума, так это то, что индикация фокуса (цвет подсветки и прямоугольник фокуса) не отрисовывается кодом DefaultDrawColumnCell, и я уверен, что должен вызывать DrawCellHighlight вместо того, чтобы делать хак FillRect, который я делаю выше.
Если я включаю DefaultDrawing, я получаю один набор глюков (странные проблемы с рисованием шрифтов), а если я отключаю его, я получаю другой набор глюков (без выделения, даже когда gdSelected).
Код в DBGrids.pas DefaultDrawColumnCell
не делает ничего, кроме рисования текста. Очевидно, что вы должны делать больше, если вы берете на себя весь код рисования самостоятельно. Однако выделенный код для рисования, встроенный в Grids.pas, от которого зависит DBGrids.pas, не предназначен для вызова из этого контекста. Я не могу понять, должен ли я вызывать DrawCellHighlight
непосредственно (показано закомментировано выше) и вычисление значений Col и Row, или, если я должен написать свою собственную сложную версию TCustomGrid.DrawCellHighlight, которая обрабатывает все различные случаи вручную.
Конечно, это так просто и очевидно, и я просто упускаю это из виду. Обратите внимание, что я должен оставить DefaultDrawing выключенным, и поэтому я должен полностью рисовать из события рисования моего владельца, и что я должен иметь возможность работать, когда сервисы тем недоступны, и я должен использовать сервисы тем, когда они доступны. Поэтому мне нужно напрямую вызывать TCustomGrid.DrawCellHighlight (и я не знаю, как это сделать), или мне нужно полностью его переопределить.
2 ответа
Вам лучше вызывать DrawCellHighlight из-за поддержки тем, что вам нужно реализовать самостоятельно. Несмотря на то, что номер строки не предоставляется OnDrawColumnCell, он не выглядит так, как будто он используется кодом DefaultDrawColumnCell, поэтому вам не нужно пытаться вычислить его внутренне:
type
tHackGrid = class(tDBGrid);
procedure TTDbGridTestForm.myGridDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if gdSelected in State then begin
tHackGrid(mygrid).DrawCellHighlight(Rect, State, Column.Index, 0);
end;
mygrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
type
tHackGrid = class(tDBGrid);
procedure MyForm.MyDbGridDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var ImageIndex: integer;
begin
if gdSelected in State
then tHackGrid(Sender).DrawCellHighlight(Rect, State, Column.Index, 0)
else tHackGrid(Sender).DrawCellBackground(Rect, Column.Color, State, Column.Index, 0);
TDbGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;