發表日期:2004-06-20 | 作者:archonwang[轉貼] 出處:http://www.delphibbs.com |
大富翁論壇版權所有
KeyLife富翁筆記
作者 : archonwang
標題 : DBGrid 應用全書(全面修訂正在進行時)
關鍵字:
分類 : 開發經驗
密級 : 公開
(評分:★★★★ , 回復: 29, 閱讀: 5682) ??
在 Delphi 語言的數據庫編程中,DBGrid 是顯示數據的主要手段之一。但是 DBGrid 缺省的外觀未免顯得單調和缺乏創意。其實,我們完全可以在我們的程序中通過編程來達到美化DBGrid 外觀的目的。通過編程,我們可以改變 DBGrid 的表頭、網格、網格線的前景色和背景色,以及相關的字體的大小和風格。
以下的示例程序演示了對 DBGrid 各屬性的設置,使 Delphi 顯示的表格就像網頁中的表格一樣漂亮美觀。
示例程序的運行:
在 Form1 上放置 DBGrid1、Query1、DataSource1 三個數據庫組件,設置相關的屬性,使 DBGrid1 能顯示表中的數據。然後,在 DBGrid1 的 onDrawColumnCell 事件中鍵入以下代碼,然後運行程序,就可以看到神奇的結果了。本代碼在 Windows98、Delphi5.0 環境下調試通過。
procedure TMainForm.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;State: TGridDrawState);
var i :integer;
begin
if gdSelected in State then Exit;
file://定義表頭的字體和背景顏色:
for i :=0 to (Sender as TDBGrid).Columns.Count-1 do
begin
(Sender as TDBGrid).Columns[i].Title.Font.Name :=’細明體’; file://字體
(Sender as TDBGrid).Columns[i].Title.Font.Size :=9; file://字體大小
(Sender as TDBGrid).Columns[i].Title.Font.Color :=$000000ff; file://字體顏色(紅色)
(Sender as TDBGrid).Columns[i].Title.Color :=$0000ff00; file://背景色(綠色)
end;
file://隔行改變網格背景色:
if Query1.RecNo mod 2 = 0 then
(Sender as TDBGrid).Canvas.Brush.Color := clInfoBk file://定義背景顏色
else
(Sender as TDBGrid).Canvas.Brush.Color := RGB(191, 255, 223); file://定義背景顏色
file://定義網格線的顏色:
DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
with (Sender as TDBGrid).Canvas do file://畫 cell 的邊框
begin
Pen.Color := $00ff0000; file://定義畫筆顏色(藍色)
MoveTo(Rect.Left, Rect.Bottom); file://畫筆定位
LineTo(Rect.Right, Rect.Bottom); file://畫藍色的橫線
Pen.Color := $0000ff00; file://定義畫筆顏色(綠色)
MoveTo(Rect.Right, Rect.Top); file://畫筆定位
LineTo(Rect.Right, Rect.Bottom); file://畫綠色的豎線
end;
end;
2003-11-5 17:30:00
發表評語???
2003-11-5 17:31:41 原來還有這個辦法啊,在沒有DevExpress之前….
我會陸續添加的
2003-11-11 17:07:42 問題: Delphi5 – 隔行改變DBGrid網格顏色 在 Form1 上放置 DBGrid1、Query1、DataSource1 三個數據庫組件,設置相關的屬性,使 DBGrid1 能顯示表中的數據。然後,在 DBGrid1 的 onDrawColumnCell 事件中鍵入以下代碼,然後運行程序
代碼:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var i:integer;
begin
if gdSelected in State then Exit; file://隔行改變網格背景色:
if adoQuery1.RecNo mod 2 = 0 then
(Sender as TDBGrid).Canvas.Brush.Color := clinfobk file://定義背景顏色
else
(Sender as TDBGrid).Canvas.Brush.Color := RGB(191, 255, 223); file://定義背景顏色
file://定義網格線的顏色:
DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State);
with (Sender as TDBGrid).Canvas do file://畫 cell 的邊框
begin
Pen.Color := $00ff0000; file://定義畫筆顏色(藍色)
MoveTo(Rect.Left, Rect.Bottom); file://畫筆定位
LineTo(Rect.Right, Rect.Bottom); file://畫藍色的橫線
Pen.Color := clbtnface; file://定義畫筆顏色(蘭色)
MoveTo(Rect.Right, Rect.Top); file://畫筆定位
LineTo(Rect.Right, Rect.Bottom); file://畫綠色
end;
end;
用BDE中的table1未能通過,顏色沒有隔行變化。
2003-11-11 17:12:09 在Delphi的DBGrid中插入其他可視組件 Delphi提供了功能強大的 DBGrid組件,以方便進行數據庫應用程序設計。但是如果我們僅僅利用DBGrid組件,每一個獲得焦點(Grid)只是一個簡單的文本編輯框,不方便用戶輸入數據。Delphi也提供了一些其他數據組件來方便用戶輸入,比如DBComboBox,DBCheckBox等組件,但這些組件卻沒有DBGrid功能強大。Delphi能不能像Visual Foxpro那樣讓DBGrid中獲得焦點網格可以是其它可視數據組件以方便用戶呢?其實我們可以通過在DBGrid中插入其他可視組件來實現這一點。
Delphi對DBGrid處理的內部機制,就是在網格上浮動一個組件——DBEdit組件。你輸入數據的網格其實是浮動DBEdit組件,其他未獲得焦點地方不過是圖像罷了。所以,在DBGrid中插入其他可視組件就是在網格上浮動一個可視組件。因此任何組件,包括從簡單的DbCheckBox到複雜的對話框,都可以在DBGrid中插入。下面就是一個如何在DBGrid中插入DBComboBox組件的步驟,採用同樣的辦法可以插入其他組件。
1、在Delphi 4.0中新建一個項目。
2、分別拖動的Data Access組件板上DataSource、Table,Data Controls組件板上DBGrid,DBComboBox四個組件到Form1上。
3、設置各個組件的屬性如下:
rcf1對像 屬性 設定植
Form1 Caption ‘在DBGrid中插入SpinEdit組件示例’
DataSource1 DataSet Table1
Table1 DatabaseName DBDEMOS
TableName ‘teacher.DBF’
Active True
DBGrid1 DataSource DataSource1
DBComboBox1 DataField SEX
DataSource DataSource1
Visible False
Strings Items. ‘男’| ‘女’
注意:我在這裡用了Teacher.dbf,那是反映教職工的性別,只能是「男」或者是「女」。
4、DrawDataCell事件是繪製單元格,當獲得焦點網格所對應的字段與組合框所對應的字段一致時,移動組合框到獲得焦點的網格上,並且使組合框可視,從而達到在DBGrid指定列上顯示DBComboBox的功能。設置DBGrid1的OnDrawDataCell事件如下:
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState);
begin
if (gdFocused in State) then
begin
if (Field.FieldName = DBComboBox1.DataField ) then
begin
DBComboBox1.Left := Rect.Left + DBGrid1.Left;
DBComboBox1.Top := Rect.Top + DBGrid1.top;
DBComboBox1.Width := Rect.Right – Rect.Left;
DBComboBox1.Height := Rect.Bottom – Rect.Top;
DBComboBox1.Visible := True;
end;
end;
end;
5、DBGrid指定單元格未獲得焦點時不顯示DBComboBox,設置DBGrid1的OnColExit事件如下:
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
If DBGrid1.SelectedField.FieldName = DBComboBox1.DataField then
begin
DBComboBox1.Visible := false;
end;
end;
6、當DBGrid指定列獲得焦點時DrawDataCell事件只是繪製單元格,並顯示DBComboBox,但是DBComboBox並沒有獲得焦點,數據的輸入還是在單元格上進行。在DBGrid1的KeyPress事件中調用SendMessage這個 Windows API函數將數據輸入傳輸到DBComboBox上,從而達到在DBComboBox上進行數據輸入。因此還要設置KeyPress事件如下:
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if (key < > chr(9)) then
begin
if (DBGrid1.SelectedField.FieldName =DBComboBox1.DataField) then
begin
DBComboBox1.SetFocus;
SendMessage(DBComboBox1.Handle,WM_Char,word(Key),0);
end;
end;
end;
程序在中文Windows 98,Delphi 4.015 下調試通過。希望本文能使你可以更加方便快捷的開發數據庫應用程序。
2003-11-11 17:17:56 鎖定DBGrid左邊的列 我在使用 Delphi3 進行數據庫編程的時候,希望 DBGRID 構件在顯示數據的時候能像FoxPro 的 BROWSE 命令一樣,鎖定左邊指定的幾列不進行滾動,請問應用什麼方法來實現?
我們知道 Delphi 的 TStringGrid 有一個屬性 FixedCols 來指定不滾動的列。雖然TDBGrid 不能直接使用這一屬性,但通過強制類型轉換也可以首先這一功能,因為這兩個類都來自 TCustomGrid 類。下面我們以 Delphi 3.0的 Demos\Db\CtrlGrid 為例來說明具體的用法。在這個例子的 TFmCtrlGrid.FormShow 過程中加入如下一行:
TStringGrid(DbGrid1).FixedCols := 2;
運行該程序,在左右移動各列時,Symbol 列不會移動。除了這種方法,也可以採用下面的方法:首先在 Form 聲明部分加上
type TMyGrid = Class(TDBGrid) end;
然後在 TFmCtrlGrid.FormShow 過程中加入:
TMyGrid(DbGrid1).FixedCols := 2;
兩者從形式上略有不同,但實質都是一樣的。我們這裡設置 FixedCols 為 2,這是因為在 DBGrid 構件最左側有個指示列,如果你將 DBGrid 的 Options 屬性的 dgIndicator 設為False,則應設置 FixedCols 為1。
2003-11-11 17:21:36 使dbgrid的某幾筆資料變色 你可在 DBGrid 元件的 DrawDataCell 事件中依資料的條件性來改變格子或文字的顏色.
如 :
OnDrawDataCell(…)
begin
with TDBGrid(Sender) do
begin
if (條件) then
Canvas.TextOut(Rect.Left + 4
Rect.Top + 2
‘要顯示的文字如表格的資料’);
end;
而你會看到 DBGrid 的顯示資料怎麼有重疊的情況那是因為原本DBGrid要顯示的資料與 TextOut 所顯示的資料重疊
解決方法 :
在 Query 元件所加入的欄位(在元件上按右鍵會有 Add Fields…的選單)在不要顯示資料的欄位的 OnGetText 事件中有一參數設定為 False;
procedure TForm1.Query1Detail1GetText(Sender: TField; var Text: string;
DisplayText: Boolean);
begin
// 決定在 DBGrid 得知表格資料時要不要顯示所得到的資料False -> 不顯示
// 就可避免與 TextOut 的文字重疊了
DisplayText : = False;
end;
end;
如果用 Delphi 3 處理很簡單.例如:對表中某字段當其數值小於0時為紅字其他為黑字.
在 DBGrid.OnDrawColumnCell(…) 中:
begin
if TableField.AsInteger < 0 then
DBGrid.Canvas.Font.Color := clRed
else
DBGrid.Canvas.Font.Color := clBlack;
DBGrid.DefaultDrawColumnCell(…);
end;
這樣對 Field 指定的格式仍舊生效不必重寫.
2003-11-11 17:25:29 實戰Delphi數據網格色彩特效 Delphi中的數據網格控件(TDbGrid)對於顯示和編輯數據庫中大量的數據起著十分重要的作用;然而,在使用數據網格控件的同時,也往往因為表格中大量的數據不易區分,而令操作者眼花繚亂。如何提高網格控件的易用性,克服它的此項不足呢?本文從改變數據網格的色彩配置角度,提出了一種解決辦法。
以下為數據網格控件的6種特殊效果的實現方法,至於數據網格控件與數據集如何連接的方法從略。
1. 縱向斑馬線效果:實現網格的奇數列和偶數列分別以不同的顏色顯示以區別相鄰的數據列。
file://在DbGrid的DrawColumnCell事件中編寫如下代碼:
Case DataCol Mod 2 = 0 of
True: DbGrid1.Canvas.Brush.Color:= clBlue; file://偶數列用藍色
False: DbGrid1.Canvas.Brush.Color:= clAqua; file://奇數列用淺綠色
End;
DbGrid1.Canvas.Pen.Mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
2. 縱向斑馬線,同時以紅色突出顯示當前單元格效果:以突出顯示當前選中的字段。
file://將上述代碼修改為:
Case DataCol Mod 2 = 0 of
True: DbGrid1.Canvas.Brush.Color:= clBlue; file://偶數列用藍色
False: DbGrid1.Canvas.Brush.Color:= clAqua; file://奇數列用淺綠色
End;
If ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then
If Not DbGrid1.SelectedRows.CurrentRowSelected then
DbGrid1.Canvas.Brush.Color:=clRed; file://當前選中單元格顯示紅色
DbGrid1.Canvas.Pen.Mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
上述兩種方法突出了列的顯示效果。
3.在數據網格中以紅色突出顯示當前選中的行。
設置DbGrid控件的Options屬性中的dgRowSelect屬性為真,Color屬性為clAqua(背景色)
在DbGrid的DrawColumnCell事件中編寫如下代碼:
if ((State = [gdSelected]) or (State=[gdSelected gdFocused])) then
DbGrid1.Canvas.Brush.color:=clRed; file://當前行以紅色顯示,其它行使用背景的淺綠色
DbGrid1.Canvas.pen.mode:=pmmask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
4.行突顯的斑馬線效果:既突出當前行,又區分不同的列(字段)。
file://其它屬性設置同3,將上述代碼修改為:
if ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then
begin
Case DataCol Mod 2 = 0 of
True : DbGrid1.Canvas.Brush.color:=clRed; file://當前選中行的偶數列顯示紅色
False: DbGrid1.Canvas.Brush.color:=clblue; file://當前選中行的奇數列顯示藍色
end;
DbGrid1.Canvas.pen.mode:=pmmask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
end;
5.橫向斑馬線, 同時以紅色突顯當前行效果。
file://其它屬性設置同3,將上述代碼修改為:
Case Table1.RecNo mod 2 = 0 of file://根據數據集的記錄號進行判斷
True : DbGrid1.Canvas.Brush.color:=clAqua; file://偶數行用淺綠色顯示
False: DbGrid1.Canvas.Brush.color:=clblue; file://奇數行用藍色表示
end;
if ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then file://選中行用紅色顯示
DbGrid1.Canvas.Brush.color:=clRed;
DbGrid1.Canvas.pen.mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
6.雙向斑馬線效果:即行間用不同色區分,同時,選中行以縱向斑馬線效果區分不同的列。
file://其它屬性設置同3,將上述代碼修改為:
Case Table1.RecNo mod 2 = 0 of file://根據數據集的記錄號進行判斷
True : DbGrid1.Canvas.Brush.color:=clAqua; file://偶數行用淺綠色顯示
False: DbGrid1.Canvas.Brush.color:= clblue; file://奇數行用藍色表示
end;
If ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then
Case DataCol mod 2 = 0 of
True : DbGrid1.Canvas.Brush.color:=clRed; file://當前選中行的偶數列用紅色
False: DbGrid1.Canvas.Brush.color:= clGreen; file://當前選中行的奇數列用綠色表示
end;
DbGrid1.Canvas.pen.mode:=pmMask;
DbGrid1.DefaultDrawColumnCell (Rect
DataCol
Column
State);
上述6種方法分別就數據網格控件的列和行的色彩進行了設置,讀者可以根據自己的需要設置特效。該程序在Delphi5中測試通過。
2003-11-13 11:11:31 點擊DBGrid的Title對查詢結果排序 關鍵詞:DBGrid 排序
欲實現點擊DBGrid的Title對查詢結果排序,想作一個通用程序,不是一事一議,例如不能在SQL語句中增加Order by …,因為SQL可能原來已經包含Order by …,而且點擊另一個Title時又要另外排序,目的是想作到象資源管理器那樣隨心所欲。
procedure TFHkdata.SortQuery(Column:TColumn);
var
SqlStr,myFieldName,TempStr: string;
OrderPos: integer;
SavedParams: TParams;
begin
if not (Column.Field.FieldKind in [fkData,fkLookup]) then exit;
if Column.Field.FieldKind =fkData then
myFieldName := UpperCase(Column.Field.FieldName)
else
myFieldName := UpperCase(Column.Field.KeyFields);
while Pos(myFieldName,’;’)<>0 do
myFieldName := copy(myFieldName,1,Pos(myFieldName,’;’)-1)+ ‘,’ + copy(myFieldName,Pos(myFieldName,’;’)+1,100);
with TQuery(TDBGrid(Column.Grid).DataSource.DataSet) do
begin
SqlStr := UpperCase(Sql.Text);
// if pos(myFieldName,SqlStr)=0 then exit;
if ParamCount>0 then
begin
SavedParams := TParams.Create;
SavedParams.Assign(Params);
end;
OrderPos := pos(‘ORDER’,SqlStr);
if (OrderPos=0) or (pos(myFieldName,copy(SqlStr,OrderPos,100))=0) then
TempStr := ‘ Order By ‘ + myFieldName + ‘ Asc’
else if pos(‘ASC’,SqlStr)=0 then
TempStr := ‘ Order By ‘ + myFieldName + ‘ Asc’
else
TempStr := ‘ Order By ‘ + myFieldName + ‘ Desc’;
if OrderPos<>0 then SqlStr := Copy(SqlStr,1,OrderPos-1);
SqlStr := SqlStr + TempStr;
Active := False;
Sql.Clear;
Sql.Text := SqlStr;
if ParamCount>0 then
begin
Params.AssignValues(SavedParams);
SavedParams.Free;
end;
Prepare;
Open;
end;
end;
2003-11-13 11:13:57 去掉DbGrid的自動添加功能
關鍵詞:DbGrid
移動到最後一條記錄時再按一下「下」就會追加一條記錄,如果去掉這項功能
procedure TForm1.DataSource1Change(Sender: TObject; Field: TField);
begin
if TDataSource(Sender).DataSet.Eof then TDataSource(Sender).DataSet.Cancel;
end;
2003-11-16 12:05:46 DBGrid不支持鼠標的上下移動的解決代碼(感謝 wangxian11 提供)自己捕捉WM_MOUSEWHEEL消息處理
private
OldGridWnd : TWndMethod;
procedure NewGridWnd (var Message : TMessage);
public
procedure TForm1.NewGridWnd(var Message: TMessage);
var
IsNeg : Boolean;
begin
if Message.Msg = WM_MOUSEWHEEL then
begin
IsNeg := Short(Message.WParamHi) < 0;
if IsNeg then
DBGrid1.DataSource.DataSet.MoveBy(1)
else
DBGrid1.DataSource.DataSet.MoveBy(-1)
end
else
OldGridWnd(Message);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OldGridWnd := DBGrid1.WindowProc ;
DBGrid1.WindowProc := NewGridWnd;
end;
2003-11-17 14:46:56 dbgrid中移動焦點到指定的行和列 dbgrid是從TCustomGrid繼承下來的,它有col與row屬性,只不過是protected的,不能直接訪問,要處理一下,可以這樣:
TDrawGrid(dbgrid1).row:=row;
TDrawGrid(dbgrid1).col:=col;
dbgrid1.setfocus;
就可以看到效果了。
1 這個方法是絕對有問題的,它會引起DBGrid內部的混亂,因為DBGrid無法定位當前紀錄,如果DBGrid只讀也就罷了(只讀還是會出向一些問題,比如原本只能單選的紀錄現在可以出現多選等等,你可以自己去試試),如果DBGrid可編輯那問題就可大了,因為當前紀錄的關係,你更改的數據字段很可能不是你想像中的
2 我常用的解決辦法是將上程序改為(隨便設置col是安全的,沒有一點問題)
Query1.first;
TDrawGrid(dbgrid1).col:=1;
dbgrid1.setfocus;
這就讓焦點移到第一行第一列當中
2003-11-17 14:55:26 如何使DBGRID網格的顏色隨此格中的數據值的變化而變化? 在做界面的時候,有時候為了突出顯示數據的各個特性(如過大或者過小等),需要通過改變字體或者顏色,本文就是針對這個情況進行的說明。
如何使DBGRID網格的顏色隨此格中的數據值的變化而變化。如<60的網格為紅色?
Delphi中數據控制構件DBGrid是用來反映數據表的最重要、也是最常用的構件。在應用程序中,如果以彩色的方式來顯示DBGrid,將會增加其可視性,尤其在顯示一些重要的或者是需要警示的數據時,可以改變這些數據所在的行或列的前景和背景的顏色。
DBGrid屬性DefaultDrawing是用來控制Cell(網格)的繪製。若DefaultDrawing的缺省設置為True,意思是Delphi使用DBGrid的缺省繪製方法來製作網格和其中所包含的數據,數據是按與特定列相連接的Tfield構件的DisplayFormat或EditFormat特性來繪製的;若將DBGrid的DefaultDrawing特性設置成False,Delphi就不繪製網格或其內容,必須自行在TDBGrid的OnDrawDataCell事件中提供自己的繪製例程(自畫功能)。
在這裡將用到DBGrid的一個重要屬性:畫布Canvas,很多構件都有這一屬性。Canvas代表了當前被顯示DBGrid的表面,你如果把另行定義的顯示內容和風格指定給DBGrid對象的Canvas,DBGrid對像會把Canvas屬性值在屏幕上顯示出來。具體應用時,涉及到Canvas的Brush屬性和FillRect方法及TextOut方法。Brush屬性規定了DBGrid.Canvas顯示的圖像、顏色、風格以及訪問Windows GDI 對像句柄,FillRect方法使用當前Brush屬性填充矩形區域,方法TextOut輸出Canvas的文本內容。
以下用一個例子來詳細地說明如何顯示彩色的DBGrid。在例子中首先要有一個DBGrid構件,其次有一個用來產生彩色篩選條件的SpinEdit構件,另外還有ColorGrid構件供自由選擇數據單元的前景和背景的顏色。
1.建立名為ColorDBGrid的Project,在其窗體Form1中依次放入所需構件,並設置屬性為相應值,具體如下所列:
Table1 DatabaseName: DBDEMOS
TableName: EMPLOYEE.DB
Active: True;
DataSource1 DataSet: Table1
DBGrid1 DataSource1: DataSource1
DefaultDrawing: False
SpinEdit1 Increment:200
Value: 20000
ColorGrid1 GridOrdering: go16*1
2.為DBGrid1構件OnDrawDataCell事件編寫響應程序:
file://這裡編寫的程序是<60的網格為紅色的情況,其他的可以照此類推
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;Field: TField; State: TGridDrawState);
begin
if Table1.Fieldbyname(′Salary′).value<=SpinEdit1.value then
DBGrid1.Canvas.Brush.Color:=ColorGrid1.ForeGroundColor
else
DBGrid1.Canvas.Brush.Color:=ColorGrid1.BackGroundColor;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.TextOut(Rect.left+2,Rect.top+2,Field.AsString);
end;
這個過程的作用是當SpinEdit1給定的條件得以滿足時,如′salary′變量低於或等於SpinEdit1.Value時,DBGrid1記錄以ColorGrid1的前景顏色來顯示,否則以ColorGrid1的背景顏色來顯示。然後調用DBGrid的Canvas的填充過程FillRect和文本輸出過程重新繪製DBGrid的畫面。
3.為SpinEdit1構件的OnChange事件編寫響應代碼:
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
DBGrid1.refresh; file://刷新是必須的,一定要刷新哦
end;
當SpinEdit1構件的值有所改變時,重新刷新DBGrid1。
4.為ColorGrid1的OnChange事件編寫響應代碼:
procedure TForm1.ColorGrid1Change(Sender: TObject);
begin
DBGrid1.refresh; file://刷新是必須的,一定要刷新哦
end;
當ColorGrid1的值有所改變時,即鼠標的右鍵或左鍵單擊ColorGrid1重新刷新DBGrid1。
5.為Form1窗體(主窗體)的OnCreate事件編寫響應代碼:
procedure TForm1.FormCreate(Sender: TObject);
begin
ColorGrid1.ForeGroundIndex:=9;
ColorGrid1.BackGroundIndex:=15;
end;
在主窗創建時,將ColorGrid1的初值設定前景為灰色,背景為白色,也即DBGrid的字體顏色為灰色,背景顏色為白色。
6.現在,可以對ColorDBGrid程序進行編譯和運行了。當用鼠標的左鍵或右鍵單擊ColorGrid1時,DBGrid的字體和背景顏色將隨之變化。
在本文中,只是簡單展示了以彩色方式顯示DBGrid的原理,當然,還可以增加程序的複雜性,使其實用化。同樣道理,也可以將這個方法擴展到其他擁有Canvas屬性的構件中,讓應用程序的用戶界面更加友好。
2003-11-17 14:58:08 判斷Grid是否有滾動條?這是一個小技巧,如果為了風格的統一的話,還是不要用了。:)
。。。
if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_VSCROLL) <> 0 then
ShowMessage(‘Vertical scrollbar is visible!’);
if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_HSCROLL) <> 0 then
ShowMessage(‘Horizontal scrollbar is visible!’);
。。。
2003-11-17 15:04:27 兩個Grid的同步滾動 在實際製作一個項目當中,有時候需要幾個grid一起同步滾動以減少用戶的操作量。希望下面那段代碼對您有一定的參考價值。
{1.}
unit SyncStringGrid;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs, Grids;
type
TSyncKind = (skBoth, skVScroll, skHScroll);
TSyncStringGrid = class(TStringGrid)
private
FInSync: Boolean;
FsyncGrid: TSyncStringGrid;
FSyncKind: TSyncKind;
{ Private declarations }
procedure WMVScroll(var Msg: TMessage); message WM_VSCROLL;
procedure WMHScroll(var Msg: TMessage); message WM_HSCROLL;
protected
{ Protected declarations }
public
{ Public declarations }
procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;
published
{ Published declarations }
property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid;
property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents(‘Samples’, [TSyncStringGrid]);
end;
procedure TSyncStringGrid.WMVScroll(var Msg: TMessage);
begin
if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skVScroll]) then
FSyncGrid.DoSync(WM_VSCROLL, Msg.wParam, Msg.lParam);
inherited;
end;
procedure TSyncStringGrid.WMHScroll(var Msg: TMessage);
begin
if not FInSync and Assigned(FSyncGrid) and (FSyncKind in [skBoth, skHScroll]) then
FSyncGrid.DoSync(WM_HSCROLL, Msg.wParam, Msg.lParam);
inherited;
end;
procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint);
begin
FInSync := True;
Perform(Msg, wParam, lParam);
FinSync := False;
end;
end.
{****************************************}
{2.}
private
OldGridProc1, OldGridProc2: TWndMethod;
procedure Grid1WindowProc(var Message: TMessage);
procedure Grid2WindowProc(var Message: TMessage);
public
{…}
procedure TForm1.Grid1WindowProc(var Message: TMessage);
begin
OldGridProc1(Message);
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or Message.msg = WM_Mousewheel)) then
begin
OldGridProc2(Message);
end;
end;
procedure TForm1.Grid2WindowProc(var Message: TMessage);
begin
OldGridProc2(Message);
if ((Message.Msg = WM_VSCROLL) or (Message.Msg = WM_HSCROLL) or (Message.msg = WM_Mousewheel)) then
begin
OldGridProc1(Message);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OldGridProc1 := StringGrid1.WindowProc;
OldGridProc2 := StringGrid2.WindowProc;
StringGrid1.WindowProc := Grid1WindowProc;
StringGrid2.WindowProc := Grid2WindowProc;
end;
2003-11-19 9:35:04 在Delphi中隨意控制DBGrid 每一行的顏色簡易方法 Delphi中使用 DBGrid 控件時,每一列都能按需要隨意地改變顏色,但要改變每一行的顏色卻很難,那麼在不重新製作新控制件的情況下,有沒有好的辦法讓DBGrid按照用戶自己要求隨意改變每一行顏色的?答案是有,下面介紹一種簡單的方法。
要改變DBGrid每一行的顏色,只要在ONDrawColumnCell事件中設定要改變顏色的行的條件,
並指定DBGrid的Canvas.Brush.color屬性並且把Canvas.pen.mode屬性設成pmmask,再調用DBGrid 的DefaultDrawColumnCell方法即可。注意在改變這兩個屬性前要先保護好原來的
Canvas.Brush.color 屬性的值,調節器用完成 DefaultDrawColumnCell 方法後要把原屬性值改
回,現以 Delphi\demos\db\clientmd 目錄下的演示程序 clintproj.dpr 為例子,做簡單說明,下面是對程序中的柵格 MemberGrid 的合條件的整行進行變色,變成黑體背景黃色的,其它不合條件的行的顏色為正常字體,白色背景,只在 DrawColumnCelL 事件中設條件其它的不變,如下:
procedure TClientForm.MemberGridDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
oldcolor:tcolor;
oldpm:tpenmode;
begin
if DM.ProjectTEAM_LEADER.Value = DM.Emp_ProjEMP_NO.Value then {设定变色的行的条件}
MemberGrid.Canvas.Font.Style := [fsBold];
MemberGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
{上面是演示程序的原内容,以下是增加部分}
if DM.ProjectTEAM_LEADER.Value =DM.Emp_ProjEMP_NO.Value then {设定变色的行的条件}
begin
oldpm:= MemberGrid.Canvas.pen.mode;
oldcolor:= MemberGrid.Canvas.Brush.color;
MemberGrid.Canvas.Brush.color:=clyellow;
MemberGrid.Canvas.pen.mode:=pmmask;
MemberGrid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
MemberGrid.Canvas.Brush.color:=oldcolor;
MemberGrid.Canvas.pen.mode:=oldpm;
end;
end;
感覺上這個方法和前面的幾個顏色控制方法的原理是一樣的,都是通過ONDrawColumnCell事件來實現變色醒目美化的功能。:)
2003-11-19 9:43:56 如何在DBGrid中能支持多項記錄的選擇 這份文檔來自國外,粗略看了一下,很有用,推薦給大家學習使用。
【Question】: How to do multi-selecting records in TDBGrid?
When you add [dgMultiSelect] to the Options property of a DBGrid, you give yourself the ability to select multiple records within the grid.
The records you select are represented as bookmarks and are stored in the SelectedRows property.
The SelectedRows property is an object of type TBookmarkList. The properties and methods are described below.
// property SelectedRows: TBookmarkList read FBookmarks;
// TBookmarkList = class
// public
{* The Clear method will free all the selected records within the DBGrid *}
// procedure Clear;
{* The Delete method will delete all the selected rows from the dataset *}
// procedure Delete;
{* The Find method determines whether a bookmark is in the selected list. *}
// function Find(const Item: TBookmarkStr;
// var Index: Integer): Boolean;
{* The IndexOf method returns the index of the bookmark within the Items property. *}
// function IndexOf(const Item: TBookmarkStr): Integer;
{* The Refresh method returns a boolean value to notify whether any orphans were dropped (deleted) during the time the record has been selected in the grid. The refresh method can be used to update the selected list to minimize the possibility of accessing a deleted record. *}
// function Refresh: Boolean; True = orphans found
{* The Count property returns the number of currently selected items in the DBGrid *}
// property Count: Integer read GetCount;
{* The CurrentRowSelected property returns a boolean value and determines whether the current row is selected or not. *}
// property CurrentRowSelected: Boolean
// read GetCurrentRowSelected
// write SetCurrentRowSelected;
{* The Items property is a TStringList of TBookmarkStr *}
// property Items[Index: Integer]: TBookmarkStr
// read GetItem; default;
// end;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables;
type
TForm1 = class(TForm)
Table1: TTable;
DBGrid1: TDBGrid;
Count: TButton;
Selected: TButton;
Clear: TButton;
Delete: TButton;
Select: TButton;
GetBookMark: TButton;
Find: TButton;
FreeBookmark: TButton;
DataSource1: TDataSource;
procedure CountClick(Sender: TObject);
procedure SelectedClick(Sender: TObject);
procedure ClearClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
procedure SelectClick(Sender: TObject);
procedure GetBookMarkClick(Sender: TObject);
procedure FindClick(Sender: TObject);
procedure FreeBookmarkClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Bookmark1: TBookmark;
z: Integer;
implementation
{$R *.DFM}
file://Example of the Count property
procedure TForm1.CountClick(Sender: TObject);
begin
if DBgrid1.SelectedRows.Count > 0 then
begin
showmessage(inttostr(DBgrid1.SelectedRows.Count));
end;
end;
file://Example of the CurrentRowSelected property
procedure TForm1.SelectedClick(Sender: TObject);
begin
if DBgrid1.SelectedRows.CurrentRowSelected then
showmessage(‘Selected’);
end;
file://Example of the Clear Method
procedure TForm1.ClearClick(Sender: TObject);
begin
dbgrid1.SelectedRows.Clear;
end;
file://Example of the Delete Method
procedure TForm1.DeleteClick(Sender: TObject);
begin
DBgrid1.SelectedRows.Delete;
end;
{*
This example iterates through the selected rows of the grid and displays the second field of the dataset.
The Method DisableControls is used so that the DBGrid will not update when the dataset is changed. The last position of the dataset is saved as a TBookmark.
The IndexOf method is called to check whether or not the bookmark is still existent.
The decision of using the IndexOf method rather than the Refresh method should be determined by the specific application.
*}
procedure TForm1.SelectClick(Sender: TObject);
var
x: word;
TempBookmark: TBookMark;
begin
DBGrid1.Datasource.Dataset.DisableControls;
with DBgrid1.SelectedRows do
if Count > 0 then
begin
TempBookmark:= DBGrid1.Datasource.Dataset.GetBookmark;
for x:= 0 to Count – 1 do
begin
if IndexOf(Items[x]) > -1 then
begin
DBGrid1.Datasource.Dataset.Bookmark:= Items[x];
showmessage(DBGrid1.Datasource.Dataset.Fields[1].AsString);
end;
end;
end;
DBGrid1.Datasource.Dataset.GotoBookmark(TempBookmark);
DBGrid1.Datasource.Dataset.FreeBookmark(TempBookmark);
DBGrid1.Datasource.Dataset.EnableControls;
end;
{*
This example allows you to set a bookmark and and then search for the bookmarked record within selected a record(s) within the DBGrid.
*}
file://Sets a bookmark
procedure TForm1.GetBookMarkClick(Sender: TObject);
begin
Bookmark1:= DBGrid1.Datasource.Dataset.GetBookmark;
end;
file://Frees the bookmark
procedure TForm1.FreeBookmarkClick(Sender: TObject);
begin
if assigned(Bookmark1) then
begin
DBGrid1.Datasource.Dataset.FreeBookmark(Bookmark1);
Bookmark1:= nil;
end;
end;
file://Uses the Find method to locate the position of the bookmarked record within the selected list in the DBGrid
procedure TForm1.FindClick(Sender: TObject);
begin
if assigned(Bookmark1) then
begin
if DBGrid1.SelectedRows.Find(TBookMarkStr(Bookmark1),z) then
showmessage(inttostr(z));
end;
end;
end.
2003-11-19 10:11:21 另外一種可以在在Delphi中隨意控制DBGrid 每一行顏色的方法 有個問題是在Delphi中使用DBGrid時,如何讓DBGrid中每一行顏色按照用戶自己的意願控
制。最初看到這個問題時,我們以為非常非常簡單,所以馬上動手準備解決它。結果卻發現不是
那麼回事,傳統方法根本不能發揮作用。在電腦面前一直坐到凌晨4點,不斷地調試,幸運地是憑借平時積累的一點編程經驗,終於找到了開門的匙鑰。現將它充公,供大家享用。
1、 數據表的建立
在Delphi的工具菜單中選擇Database desktop,在數據庫DBDemos下建立一個名為
example.db的數據表。數據表的字段和內容如下:
Name Age Wage
張山 25 500
王武 57 1060
李市 30 520
劉牛 28 390
2、創建基於TDBGrid的TColoredDBGrid組件
在Delphi組件菜單中,選擇New Component,在彈出對話框中作以下設置:
Ancestor Type = TDBGrid
Class Name = TColoredDBGrid
然後單擊OK按鈕,Delphi自動完成組件基本框架的定義。增添OnDRawColoredDBGrid事件並
使它出現在Object Inspector的Events中以便在應用程序中設定改變行顏色的條件。重載
DrawCell方法,只能自己繪製單元格。不能通過在OnDrawColumnCell來設置顏色,因為在
OnDrawColumnCell改變單元格的顏色會再次觸發OnDrawColumnCell。
下面就是所創建組件的源程序 。
3、建立應用程序進行驗證。
在Delphi文件菜單中選擇New建立新的應用程序工程Project1和主窗體Form1,設置Form1的
Caption屬性為「控制DBGrid行顏色的示例」。在主窗體上添加Data Source、Table、Button和
ColoredDBGrid組件。設置各組件的屬性如下:
Table1.Database=』DBDemos』
Table1.Tablename=』example.db』
Datasource1.Dataset=Table1
ColoredDBGrid1.Datasource=DataSource1
Button1.Caption=』退出』
在ColoredDBGrid1的onDRawColoredDBGrid事件中輸入下列代碼,設定由Wage(工資)來決
定在ColoredDBGrid1各行的顏色。
procedure TForm1.ColoredDBGrid1 DRawColoredDBGrid (Sender: TObject; Field: TField; var Color: TColor; var Font: TFont);
Var
p : Integer;
begin
p := Table1.FindField(‘wage’).AsInteger;
file://取得當前記錄的Wage字段的值。
if (p < 500) then begin
file://程序將根據wage值設置各行的顏色。
Color := clGreen;
Font.Style := [fsItalic];
file://不僅可以改變顏色,還可以改變字體
end;
if(p >= 500) And (p < 800) then
Color := clRed;
if(p >=800) then begin
Color := clMaroon;
Font.Style := [fsBold];
end;
end;
file://用『退出』按鈕結束程序運行。
procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;
2003-11-19 10:16:11 在一個Dbgrid中顯示多數據庫 在數據庫編程中,不必要也不可能將應用程序操作的所有數據庫字段放入一個數據庫文件中。正確的數據庫結構應是:將數據庫字段放入多個數據庫文件,相關的數據庫都包含一個唯一
的關鍵字段,在多數據庫結構裡可以建立聯繫。
例如:要編製一個人事管理程序,為簡化演示程序,只建立兩個數據庫,每個數據庫都只建
立兩個字段。
個人簡介 jianjie.dbf,由人事處維護;工資情況 gongzi.dbf,由財務處維護。
1.數據庫的建立
進入DataBase Desktop,建立數據庫結構如下:
jianjie.dbf
編號 字段名:bianhao size:4 type:number
姓名 字段名:xingming size:10 type:character
gongzi.dbf
編號 字段名:bianhao size:4 type:number
工資 字段名:gongzi size:4 Dec 2 type:number
注意: 兩個數據庫的bianhao字段的size、type必須一致。實際上,兩數據庫文件可以分佈
在網絡的不同計算機上,為便於演示,分別存為〞c: \test\jianjie.dbf〞和 〞c:\test
\gongzi.dbf〞。
2.應用程序的編制
啟動Delphi, 新建一個工程,在窗體中加入Query控件Query1,databasename屬性設為c:
\test;
加入DataSource控件datasource1, DataSet屬性設為Query1; 加入DbGrid控件 dbgrid1,
DataSource屬性設為DataSource1,將Query1.sql屬性設為
SELECT DISTINCT A.bianhao,a.xingming, b.gongzi
FROM 〞jianjie.dbf〞 A, 〞gongzi.DBF〞 b
WHERE A.bianhao=b.bianhao
再將Query1.enabled屬性設為True, 不用編譯, DbGrid1就會顯示: bianhao,
xingming, gongzi三個字段。如果jianjie.dbf和gongzi.dbf中有記錄,則記錄會顯示出來。因
篇幅所限,此文只介紹了Dbgrid中顯示多個數據庫內容的一般方法,讀者可在此基礎上進行完
善,使該方法更好地適應您的需要。
2003-11-19 10:19:40 在 DBGrid 中如何讓回車變為光標右移動
在Form.forbidden事件中寫如下代碼:
if Key = #13 then
if ActiveControl = DBGrid1 then begin
TDBGrid(ActiveControl).SelectedIndex := TDBGrid(ActiveControl).SelectedIndex + 1;
Key := #0;
end;
有2點需要注意:
1.當光標達到DBGird最右列的時候,再按回車,光標還會停留在原地。
2.Key := #0
2003-11-19 10:25:07 從 DBGrid 中複製記錄procedure TForm1.DBGrid1DblClick(Sender: TObject);
var
x : integer ;
HadToOpen : boolean ;
begin
with Sender as TDBGrid do begin
HadToOpen := not tTarget.Active ;
if HadToOpen then
tTarget.Active := True ;
tTarget.Append ;
for x := 0 to FieldCount – 1 do
case Fields[x].DataType of
ftBoolean : tTarget.FieldByName(Fields[x].FieldName).AsBoolean := Fields[x].AsBoolean
ftString : tTarget.FieldByName(Fields[x].FieldName).AsString := Fields[x].AsString
ftFloat : tTarget.FieldByName(Fields[x].FieldName).AsFloat := Fields[x].AsFloat
ftInteger : tTarget.FieldByName(Fields[x].FieldName).AsInteger := Fields[x].AsInteger
ftDate : tTarget.FieldByName(Fields[x].FieldName).AsDateTime := Fields[x].AsDateTime ;
end ;
tTarget.Post ;
if HadToOpen then
tTarget.Active := False ;
end ;
end;
2003-11-19 10:27:58 使用 DBGrid 的復選項(請參考如何在DBGrid中能支持多項記錄的選擇)procedure TForm1.SelectClick(Sender: TObject);
var
x: word;
TempBookmark: TBookMark;
begin
DBGrid1.Datasource.Dataset.DisableControls;
with DBgrid1.SelectedRows do
if Count <> 0 then
begin
TempBookmark:= DBGrid1.Datasource.Dataset.GetBookmark;
for x:= 0 to Count – 1 do
begin
if IndexOf(Items[x]) > -1 then
begin
DBGrid1.Datasource.Dataset.Bookmark:= Items[x];
showmessage(DBGrid1.Datasource.Dataset.Fields[1].AsString);
end;
end;
end;
DBGrid1.Datasource.Dataset.GotoBookmark(TempBookmark);
DBGrid1.Datasource.Dataset.FreeBookmark(TempBookmark);
DBGrid1.Datasource.Dataset.EnableControls;
end;
2003-11-19 10:32:27 在DBGrid上Drag & Drop(拖放)我們在做程序中發現,如果能夠讓用戶將一個Edit的內容直接拖放到一個DBGrid裡,會顯得很方便,但在程序編製過程中發現,似乎拖放只能拖放到當前的記錄上,那假如要拖放到其他記錄又怎麼辦呢,總不能讓用戶先選擇記錄,然後再拖放吧。
後來,通過研究發現,當用鼠標點DBGrid時,DBGrid會自動將記錄指針移動到所點擊的記錄上,這就給了我一個思路,讓程序模擬在DBGrid上的一次點擊先讓光標移動到那條記錄上,然後就可以將拖放的數據寫入DBgrid裡面了。
通過事實證明這個思路是可行的。下面,我就告訴大家我的做法:
1) 首先在Form上放一個DBGrid,並它能夠顯示記錄,(這比較簡單,就不用多說了)
2) 在Form上放一個Edit
3) 修改Edit的屬性,把DragMode改為dmAutoMatic, 讓用戶能夠拖放
4) 在Dbgrid的DragOver事件中增加如下代碼: 讓它能夠接收 Drag & drop
procedure TForm1.DBGrid1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
accept:=true;
end;
5) 在Dbgrid的DragDrop事件中增加如下代碼: 讓它能夠自動跳到光標所指定的記錄上
procedure TForm1.DBGrid1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
if Source<>Edit1 then exit;
with Sender as TDbGrid do begin
Perform(wm_LButtonDown,0,MakeLong(x,y));
PerForm(WM_LButtonUp, 0,MakeLong(x,y));
SelectedField.Dataset.edit;
SelectedField.AsString:=Edit1.text;
end;
end;
至此,我們就實現了想要的功能,其中PerForm是TControl的一個通用方法目的是繞過Windows本身的消息循環,而將消息直接發給要發的Control,其具體使用方法請參考Delphi的幫助。
2003-11-19 10:39:19 如何使DBGrid的指針不移動?
【問題】:我用DBGRID顯示TABLE中的內容,現在我要從頭到尾讀一遍TABLE裡的數據,用
Table1.First,Next來做會使DBGRID裡面的指針也跟著跑,怎麼才能使這時候DBGRID裡面的指針不
動呢?
【答案】:使用如下代碼即可:
with DataSet do
try
DisableControls;
Do_something;
finally
EnableControls;
end;
2003-11-19 10:42:14 如何動態更新DBGrid的顏色?(請同時參考「如何使DBGRID網格的顏色隨此格中的數據值的變化而變化?」) DBGrid控件是一個有許多用戶接口的顯示數據庫的控件,以下的程序告訴您如何根據顯示的內容改變字體的顯示顏色。例如,如果一個城市的人口大於200萬,我們就讓它顯示為藍色。使用的控件事件為DBGrid.OnDrawColumeCell.
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect:TRect;DataCol:
Integer; Column: TColumn; State: TGridDrawState);
begin
if Table1.FieldByName(‘Population’).AsInteger > 20000000 then
DBGrid1.Canvas.Font.Color := clBlue;
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
上面的例子是簡單的,但是你可以根據自己的需要擴充,例如字體也變化等,甚至你可以調用畫圓的函數在數字上畫上一個紅色的圓圈。
2003-11-19 10:45:14 使用DBGrid顯示日期 在使用 DBGRID 控件時顯示 DATATIME 時其年份是為2位的,但我們在步入2000年後需要顯示的日期是4位,如:1998、2001。在數據庫中該字段只有在2000年後才會顯示4位,怎麼辦呢? 下面我們就讓該字段在DBGRID控件中也顯示4位的日期格式: 雙擊 Table1 控件,就會出現 form1.table 窗體,擊右鍵,選 Add Fields…,選擇日期字段後按ok,窗體中就出現了數據庫的日