首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

DBGrid 兼具整列選取與儲存格編輯:繞過 dgRowSelect 限制

     編輯:關於C++

問題背景

DBGrid 設定 dgRowSelect = true 可整列高亮,但會導致:

  1. 無法進入儲存格編輯模式
  2. 水平捲動至右側後,點擊其他列畫面會跳回最左欄,體驗極差

若關閉 dgRowSelect,雖可編輯且捲動正常,但失去整列選取視覺提示。

解決思路:偽裝整列選取

在 OnDrawColumnCell 事件中,手動繪製當前資料列背景色 模擬整列選取效果,同時保持 dgRowSelect = false、dgEditing = true、DefaultDrawing = false。

Delphi 版核心邏輯(原理參考)

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++ Builder 移植關鍵:存取 protected 成員

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);
}

使用方式

  1. DBGrid 設定:Options >> dgRowSelect = false、dgEditing = true、DefaultDrawing = false
  2. OnDrawColumnCell 事件呼叫 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 實作欄位排序視覺回饋
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved