在DBGrid中可選中行而又可進入編輯狀態
如何在DBGrid中選中行,而又讓它可以進入編輯狀態?
也許你會問我這有什麼用?呵呵,做資料庫應用的兄弟們會深有感觸,當用DBGrid顯示的欄位過多時,使用者不得不拉動最下面的滾動條,去看最右邊的東西,如果沒有設定DBGrid->Options[dgRowSelect],那麼,拉到最右邊之後,很有可能看序列的;如果設定了DBGrid->Options[dgRowSelect],則在拉到最右邊之後,不會看序列,但是滑鼠點選其它行(不是當前選中行)時,DBGrid的檢視一下子就會回到顯示最左邊的那一列,確實很麻煩,使用者不得不一次又一次的拖運下面的滾動條。
一同事因這個問題而苦惱,而我又在CSDN的文件庫中看到了這篇文章:
《DBGrid使用全書(五)》,連結:http://dev.csdn.net/article/51/51845.shtm,是Delphi版本的,核心程式碼如下:
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)
// 本文轉自 C++Builder研究 - http://www.ccrun.com/article.asp?i=637&d=2724wn
{
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);
}
原文連結: