程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 在DBGrid中可選中行而又可進入編輯狀態

在DBGrid中可選中行而又可進入編輯狀態

編輯:關於C++

如何在DBGrid中選中行,而又讓它可以進入編輯狀態?

也許你會問我這有什麼用?呵呵,做數據庫應用的兄弟們會深有感觸,當用DBGrid顯示的字段過多時,用戶不得不拉動最下面的滾動條,去看最右邊的東西,如果沒有設置DBGrid->Options[dgRowSelect],那麼,拉到最右邊之後,很有可能看串行的;如果設置了DBGrid->Options[dgRowSelect],則在拉到最右邊之後,不會看串行,但是鼠標點擊其它行(不是當前選中行)時,DBGrid的視圖一下子就會回到顯示最左邊的那一列,確實很麻煩,用戶不得不一次又一次的拖運下面的滾動條。

核心代碼如下:

type
   TMyDBGrid=class(TDBGrid);
   //////////////////////////////////
//DBGrid1.Options->dgEditing=True
//DBGrid1.Options->dgRowSelect=False
   procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
   DataCol: Integer; Column: TColumn; State: TGridDrawState);
   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;

他的解決辦法是:曲線救國,取消DBGrid->Options[dgRowSelect],把當前選中行的背景繪制成藍色,就象是被選中一樣,想法確實很妙。我們公司使用C++Builder,我只好把這段代碼改為C++Builder版本的,這時,我才發現這段代碼的精妙之處。

我發現DataLink屬性是TCustomDBGrid中聲明為protected的,而在DBGrid中並未聲明它的可見性,因此,不能直接使用它;而Row屬性則是在TCustomGrid中聲明為protected的,在TCustomGrid的子類中也未聲明它的可見性,那麼,這段代碼為何在Delphi中運行的很好?

原因就在於:ObjectPascal的單元封裝,在同一個單元中定義的類,互相之間是友員的關系,我們再來看這段代碼的開頭:

type

TMyDBGrid = class(TDBGrid);

聲明了一個TMyDBGrid類,那麼,當前這個窗體類就和TMyDBGird類互為友元了,那麼當然當前窗體類可以直接訪問TMyDBGrid的私有屬性Row和DataLink了,一切都明了了,那麼用C++就好實現了,核心代碼如下:

void __fastcall TMainForm::LineSelEdit(TObject *Sender,const TRect &Rect, int DataCol, TColumn *Column,TGridDrawState State)
   {
     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);
   }

我把它封裝成一個函數,函數的參數與DBGrid的OnDrawDataCell的參數一樣,使用它的方法就是取消設置DBGrid->Options[dgRowSelect],然後設置DBGrid->DefaultDrawing = false,然後在這個DBGrid的OnDrawDataCell事件中調用這個函數,如下:

void __fastcall TMainForm::DBGridDrawColumnCell(TObject *Sender,
const TRect &Rect, int DataCol, TColumn *Column,
      TGridDrawState State)
   {
this->LineSelEdit(Sender,Rect,DataCol,Column,State);
   }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved