DBGrid 設定 dgRowSelect = true 可整列高亮,但會導致:
若關閉 dgRowSelect,雖可編輯且捲動正常,但失去整列選取視覺提示。
在 OnDrawColumnCell 事件中,手動繪製當前資料列背景色 模擬整列選取效果,同時保持 dgRowSelect = false、dgEditing = true、DefaultDrawing = false。
type TMyDBGrid = class(TDBGrid); // 同單元友元存取 protected 成員
procedure TForm1.DBGrid1DrawColumnCell(...);
begin
with TMyDBGrid(Sender) do begin
if DataLink.ActiveRecord = Row - 1 then begin // 當前資料列
Canvas.Font.Color := clWhite;
Canvas.Brush.Color := $00800040; // 深藍背景
end else begin
Canvas.Brush.Color := Color;
Canvas.Font.Color := Font.Color;
end;
DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
end;
C++ 無 Delphi 的「單元友元」機制,需透過本地類別繼承暴露 Row 與 DataLink:
void __fastcall TMainForm::LineSelEdit(TObject* Sender, const TRect& Rect,
int DataCol, TColumn* Column, TGridDrawState State) {
// 本地類別暴露 protected 成員
class TMyGridBase : public TCustomGrid {
public: __property Row;
};
class TMyGrid : public TCustomDBGrid {
public: __property DataLink;
};
TMyGrid* MyGrid = (TMyGrid*)Sender;
TMyGridBase* MyGridBase = (TMyGridBase*)Sender;
TDBGrid* Grid = (TDBGrid*)Sender;
if (MyGrid->DataLink->ActiveRecord == MyGridBase->Row - 1) {
Grid->Canvas->Font->Color = clWhite;
Grid->Canvas->Brush->Color = TColor(0x00800040);
} else {
Grid->Canvas->Brush->Color = Grid->Color;
Grid->Canvas->Font->Color = Grid->Font->Color;
}
Grid->DefaultDrawColumnCell(Rect, DataCol, Column, State);
}
Options >> dgRowSelect = false、dgEditing = true、DefaultDrawing = falseOnDrawColumnCell 事件呼叫 LineSelEdit(...)void __fastcall TMainForm::DBGridDrawColumnCell(TObject* Sender,
const TRect& Rect, int DataCol, TColumn* Column, TGridDrawState State) {
LineSelEdit(Sender, Rect, DataCol, Column, State);
}
DataLink.ActiveRecord:資料集中當前記錄索引(0-based)Row:格網中視覺列號(1-based,第 0 列為標題列)Canvas.Brush/Font 後呼叫 DefaultDrawColumnCell 讓 VCL 繪製文字內容| 優點 | 缺點 |
|---|---|
| 保留儲存格編輯功能 | 需關閉 DefaultDrawing,自繪負擔稍增 |
| 水平捲動不跳回左欄 | 選取列高亮非系統原生,細節需自行調校 |
| 程式碼簡潔,無需第三方元件 | 若需多選,邏輯較複雜 |
OnCellClick 實作單點編輯模式OnTitleClick 實作欄位排序視覺回饋