procedure TMainForm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn;State: TGridDrawState); var i :integer; begin if gdSelected in State then Exit; //定義表頭的字體和背景顏色: for i :=0 to (Sender as TDBGrid).Columns.Count-1 do begin (Sender as TDBGrid).Columns[i].Title.Font.Name :='宋體'; //字體 (Sender as TDBGrid).Columns[i].Title.Font.Size :=9; //字體大小 (Sender as TDBGrid).Columns[i].Title.Font.Color :=$000000ff; //字體顏色(紅色) (Sender as TDBGrid).Columns[i].Title.Color :=$0000ff00; //背景色(綠色) end; //隔行改變網(wǎng)格背景色: if Query1.RecNo mod 2 = 0 then (Sender as TDBGrid).Canvas.Brush.Color := clInfoBk //定義背景顏色 else (Sender as TDBGrid).Canvas.Brush.Color := RGB(191, 255, 223); //定義背景顏色 //定義網(wǎng)格線的顏色: DBGrid1.DefaultDrawColumnCell(Rect,DataCol,Column,State); with (Sender as TDBGrid).Canvas do //畫 cell 的邊框 begin Pen.Color := $00ff0000; //定義畫筆顏色(藍(lán)色) MoveTo(Rect.Left, Rect.Bottom); //畫筆定位 LineTo(Rect.Right, Rect.Bottom); //畫藍(lán)色的橫線 Pen.Color := $0000ff00; //定義畫筆顏色(綠色) MoveTo(Rect.Right, Rect.Top); //畫筆定位 LineTo(Rect.Right, Rect.Bottom); //畫綠色的豎線 end; end; ----------------------------------------------- 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; ----------------------------------------------- procedure TForm1.DBGrid1ColExit(Sender: TObject); begin If DBGrid1.SelectedField.FieldName = DBComboBox1.DataField then begin DBComboBox1.Visible := false; end; end; ----------------------------------------------- 在DbGrid的DrawColumnCell事件中編寫如下代碼: Case DataCol Mod 2 = 0 of True: DbGrid1.Canvas.Brush.Color:= clBlue; file://偶數(shù)列用藍(lán)色 False: DbGrid1.Canvas.Brush.Color:= clAqua; file://奇數(shù)列用淺綠色 End; DbGrid1.Canvas.Pen.Mode:=pmMask; DbGrid1.DefaultDrawColumnCell (Rect DataCol Column State); ----------------------------------------------- Case DataCol Mod 2 = 0 of True: DbGrid1.Canvas.Brush.Color:= clBlue; file://偶數(shù)列用藍(lán)色 False: DbGrid1.Canvas.Brush.Color:= clAqua; file://奇數(shù)列用淺綠色 End; If ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then If Not DbGrid1.SelectedRows.CurrentRowSelected then DbGrid1.Canvas.Brush.Color:=clRed; file://當(dāng)前選中單元格顯示紅色 DbGrid1.Canvas.Pen.Mode:=pmMask; DbGrid1.DefaultDrawColumnCell (Rect DataCol Column State); ----------------------------------------------- 設(shè)置DbGrid控件的Options屬性中的dgRowSelect屬性為真,Color屬性為clAqua(背景色) 在DbGrid的DrawColumnCell事件中編寫如下代碼: if ((State = [gdSelected]) or (State=[gdSelected gdFocused])) then DbGrid1.Canvas.Brush.color:=clRed; file://當(dāng)前行以紅色顯示,其它行使用背景的淺綠色 DbGrid1.Canvas.pen.mode:=pmmask; DbGrid1.DefaultDrawColumnCell (Rect DataCol Column State); ----------------------------------------------- if ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then begin Case DataCol Mod 2 = 0 of True : DbGrid1.Canvas.Brush.color:=clRed; file://當(dāng)前選中行的偶數(shù)列顯示紅色 False: DbGrid1.Canvas.Brush.color:=clblue; file://當(dāng)前選中行的奇數(shù)列顯示藍(lán)色 end; DbGrid1.Canvas.pen.mode:=pmmask; DbGrid1.DefaultDrawColumnCell (Rect DataCol Column State); end; ----------------------------------------------- 橫向斑馬線, 同時以紅色突顯當(dāng)前行效果。 file://其它屬性設(shè)置同3,將上述代碼修改為: Case Table1.RecNo mod 2 = 0 of file://根據(jù)數(shù)據(jù)集的記錄號進(jìn)行判斷 True : DbGrid1.Canvas.Brush.color:=clAqua; file://偶數(shù)行用淺綠色顯示 False: DbGrid1.Canvas.Brush.color:=clblue; file://奇數(shù)行用藍(lán)色表示 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); ----------------------------------------------- 雙向斑馬線效果:即行間用不同色區(qū)分,同時,選中行以縱向斑馬線效果區(qū)分不同的列。 file://其它屬性設(shè)置同3,將上述代碼修改為: Case Table1.RecNo mod 2 = 0 of file://根據(jù)數(shù)據(jù)集的記錄號進(jìn)行判斷 True : DbGrid1.Canvas.Brush.color:=clAqua; file://偶數(shù)行用淺綠色顯示 False: DbGrid1.Canvas.Brush.color:= clblue; file://奇數(shù)行用藍(lán)色表示 end; If ((State = [gdSelected]) or (State=[gdSelectedgdFocused])) then Case DataCol mod 2 = 0 of True : DbGrid1.Canvas.Brush.color:=clRed; file://當(dāng)前選中行的偶數(shù)列用紅色 False: DbGrid1.Canvas.Brush.color:= clGreen; file://當(dāng)前選中行的奇數(shù)列用綠色表示 end; DbGrid1.Canvas.pen.mode:=pmMask; DbGrid1.DefaultDrawColumnCell (Rect DataCol Column State); ----------------------------------------------- DBGrid不支持鼠標(biāo)的上下移動的解決代碼(感謝 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; ----------------------------------------------- dbgrid中移動焦點到指定的行和列 dbgrid是從TCustomGrid繼承下來的,它有col與row屬性,只不過是protected的,不能直接訪問,要處理一下,可以這樣: Query1.first; TDrawGrid(dbgrid1).col:=1; dbgrid1.setfocus; ----------------------------------------------- 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; ----------------------------------------------- 1.為SpinEdit1構(gòu)件的OnChange事件編寫響應(yīng)代碼: procedure TForm1.SpinEdit1Change(Sender: TObject); begin DBGrid1.refresh; //刷新是必須的 end; 當(dāng)SpinEdit1構(gòu)件的值有所改變時,重新刷新DBGrid1。 2.為ColorGrid1的OnChange事件編寫響應(yīng)代碼: procedure TForm1.ColorGrid1Change(Sender: TObject); begin DBGrid1.refresh; //刷新是必須的 end; 當(dāng)ColorGrid1的值有所改變時,即鼠標(biāo)的右鍵或左鍵單擊ColorGrid1重新刷新DBGrid1。 3.為Form1窗體(主窗體)的OnCreate事件編寫響應(yīng)代碼: procedure TForm1.FormCreate(Sender: TObject); begin ColorGrid1.ForeGroundIndex:=9; ColorGrid1.BackGroundIndex:=15; end; ----------------------------------------------- 判斷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!'); ----------------------------------------------- 1、 數(shù)據(jù)表的建立 在Delphi的工具菜單中選擇Database desktop,在數(shù)據(jù)庫DBDemos下建立一個名為 example.db的數(shù)據(jù)表。數(shù)據(jù)表的字段和內(nèi)容如下: Name Age Wage 張山 25 500 王武 57 1060 李市 30 520 劉牛 28 390 2、創(chuàng)建基于TDBGrid的TColoredDBGrid組件 在Delphi組件菜單中,選擇New Component,在彈出對話框中作以下設(shè)置: Ancestor Type = TDBGrid Class Name = TColoredDBGrid 然后單擊OK按鈕,Delphi自動完成組件基本框架的定義。增添OnDRawColoredDBGrid事件并 使它出現(xiàn)在Object Inspector的Events中以便在應(yīng)用程序中設(shè)定改變行顏色的條件。重載 DrawCell方法,只能自己繪制單元格。不能通過在OnDrawColumnCell來設(shè)置顏色,因為在 OnDrawColumnCell改變單元格的顏色會再次觸發(fā)OnDrawColumnCell。 下面就是所創(chuàng)建組件的源程序 。 3、建立應(yīng)用程序進(jìn)行驗證。 在Delphi文件菜單中選擇New建立新的應(yīng)用程序工程Project1和主窗體Form1,設(shè)置Form1的 Caption屬性為“控制DBGrid行顏色的示例”。在主窗體上添加Data Source、Table、Button和 ColoredDBGrid組件。設(shè)置各組件的屬性如下: Table1.Database=’DBDemos’ Table1.Tablename=’example.db’ Datasource1.Dataset=Table1 ColoredDBGrid1.Datasource=DataSource1 Button1.Caption=’退出’ 在ColoredDBGrid1的onDRawColoredDBGrid事件中輸入下列代碼,設(shè)定由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; //取得當(dāng)前記錄的Wage字段的值。 if (p < 500) then begin //程序?qū)⒏鶕?jù)wage值設(shè)置各行的顏色。 Color := clGreen; Font.Style := [fsItalic]; //不僅可以改變顏色,還可以改變字體 end; if(p >= 500) And (p < 800) then Color := clRed; if(p >=800) then begin Color := clMaroon; Font.Style := [fsBold]; end; end; ----------------------------------------------- unit NewDBGrid; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DB, Grids, DBGrids, Excel97; type TDrawFieldCellEvent = procedure(Sender: TObject; Field: TField; var Color: TCOlor; var Font: TFont; Row: Longint) of object; //新的數(shù)據(jù)控件由 TDBGrid 繼承而來 TNewDBGrid = class(TDBGrid) private //私有變量 FWZebra: Boolean; //是否顯示斑馬顏色 FWFirstColor: TColor; //單數(shù)行顏色 FWSecondColor: TCOlor; //雙數(shù)行顏色 FDrawFieldCellEvent: TDrawFieldCellEvent; procedure AutoInitialize; //自動初使化過程 procedure AutoDestroy; function GetWFirstColor: TColor; //FirstColor 的讀寫函數(shù)及過程 procedure SetWFirstColor(Value: TColor); function GetWSecondColor: TCOlor; procedure SetWSecondColor(Value: TColor); function GetWZebra: Boolean; procedure SetWZebra(Value: Boolean); protected procedure Scroll(Distance: Integer); override; //本控件的重點過程 procedure DrawCell(Acol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property WZebra: Boolean read GetWZebra write SetWZebra; property OnDblClick; property OnDragDrop; property OnKeyUp; property OnKeyDown; property OnKeyPress; property OnEnter; property OnExit; property OnDrawDataCell; property WFirstColor: TColor read GetWFirstColor write SetWFirstColor; property WSecondColor: TColor read GetWSecondColor write SetWSecondColor; end; procedure Register; implementation procedure Register; begin RegisterComponents('Data Controls', [TNewDBGrid]); end; procedure TNewDBGrid.AutoInitialize; begin FWFirstColor := RGB(239, 254, 247); FWSecondColor := RGB(249, 244, 245); {可以在次添加需要的其它控件及初使化參數(shù)} end; procedure TNewDBGrid.AutoDestroy; begin {在這里釋放自己添加參數(shù)等占用的系統(tǒng)資源} end; procedure TNewDBGrid.SetWZebra(Value: Boolean); begin FWZebra := Value; Refresh; end; function TNewDBGrid.GetWZebra: Boolean; begin Result := FWZebra; end; function TNewDBGrid.GetWFirstColor: TColor; begin Result := FWFirstColor; end; procedure TNewDBGrid.SetWFirstColor(Value: TColor); begin FWFirstColor := Value; Refresh; end; function TNewDBGrid.GetWSecondColor: TColor; begin Result := FWSecondColor; end; procedure TNewDBGrid.SetWSecondColor(Value: TColor); begin FWSecondColor := Value; Refresh; end; constructor TNewDBGrid.Create(AOwner: TComponent); begin inherited Create(AOwner); AutoInitialize; end; destructor TNewDBGrid.Destroy; begin AutoDestroy; inherited Destroy; end; //實現(xiàn)斑馬效果 procedure TNewDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); var OldActive: Integer; Highlight: Boolean; Value: string; DrawColumn: Tcolumn; cl: TColor; fn: TFont; begin {如果處于控件裝載狀態(tài),則直接填充顏色后退出} if csLoading in ComponentState then begin Canvas.Brush.Color := Color; Canvas.FillRect(ARect); Exit; end; if (gdFixed in AState) and (ACol - IndicatorOffset < 0) then begin inherited DrawCell(ACol, ARow, ARect, AState); Exit; end; {對于列標(biāo)題,不用任何修飾} if (dgTitles in Options) and (ARow = 0) then begin inherited DrawCell(ACol, ARow, ARect, AState); Exit; end; if (dgTitles in Options) then Dec(ARow); Dec(ACol, IndicatorOffset); if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then begin {縮減ARect,以便填寫數(shù)據(jù)} InflateRect(ARect, -1, -1); end else with Canvas do begin DrawColumn := Columns[ACol]; Font := DrawColumn.Font; Brush.Color := DrawColumn.Color; Font.Color := DrawColumn.Font.Color; if FWZebra then //如果屬性WZebra為True則顯示斑馬紋 if Odd(ARow) then Brush.Color := FWSecondColor else Brush.Color := FWFirstColor; if (DataLink = nil) or not DataLink.Active then FillRect(ARect) else begin Value := ''; OldActive := DataLink.ActiveRecord; try DataLink.ActiveRecord := ARow; if Assigned(DrawColumn.Field) then begin Value := DrawColumn.Field.DisplayText; if Assigned(FDrawFieldCellEvent) then begin cl := Brush.Color; fn := Font; FDrawFieldCellEvent(self, DrawColumn.Field, cl, fn, ARow); Brush.Color := cl; Font := fn; end; end; Highlight := HighlightCell(ACol, ARow, Value, AState); if Highlight and (not FWZebra) then begin Brush.Color := clHighlight; Font.Color := clHighlightText; end; if DefaultDrawing then DefaultDrawColumnCell(ARect, ACol, DrawColumn, AState); if Columns.State = csDefault then DrawDataCell(ARect, DrawColumn.Field, AState); DrawColumnCell(ARect, ACol, DrawColumn, AState); finally DataLink.Activerecord := OldActive; end; if DefaultDrawing and (gdSelected in AState) and ((dgAlwaysShowSelection in Options) or Focused) and not (csDesigning in Componentstate) and not (dgRowSelect in Options) and (ValidParentForm(self).ActiveControl = self) then begin //顯示當(dāng)前光標(biāo)處為藍(lán)底黃字,同時加粗顯示 Windows.DrawFocusRect(Handle, ARect); Canvas.Brush.COlor := clBlue; Canvas.FillRect(ARect); Canvas.Font.Color := clYellow; Canvas.Font.Style := [fsBold]; DefaultDrawColumnCell(ARect, ACol, DrawColumn, AState); end; end; end; if (gdFixed in AState) and ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then begin InflateRect(ARect, -2, -2); DrawEdge(Canvas.Handle, ARect, BDR_RAISEDINNER, BF_BOTTOMRIGHT); DrawEdge(Canvas.Handle, ARect, BDR_SUNKENINNER, BF_TOPLEFT); end; end; //如果移動光標(biāo)等,則需要刷新顯示DBGrid procedure TNewDBGrid.Scroll(Distance: Integer); begin inherited Scroll(Distance); refresh; end; end. ----------------------------------------------- 在DBGrid控件中顯示圖形 如果在數(shù)據(jù)庫中設(shè)置了一個為BLOB類型的字段用于保存圖形,在使用DBGrid控件顯示時,在表格中顯示的是BLOB,而無法顯示出圖形,當(dāng)然,有一些第三方控件可以顯示出圖形,但是要去找第三方控件不是一件容易的事,而且有些好用的都需要付費。能不能在DBGrid中顯示圖形呢?答案是肯定的。 在DBGrid的OnDrawCell事件中加入如下代碼即可在DBGrid控件中顯示圖形。 var Bmp: TBitmap; begin if (Column.Field.DataTyp = ftBLOB) or (Column.Field.DataTyp = ftGraphic) then begin Bmp:=TBitmap.Create; try Bmp.Assign(Column.Field); DBGrid1.Canvas.StretchDraw(Rect,Bmp); Bmp.Free; Except Bmp.Free; end; end; end; ----------------------------------------------- 將 DBGrid 中的內(nèi)容輸出至 Excel 或 ClipBoard //注意:下面的方法必須包含 ComObj, Excel97 單元 //----------------------------------------------------------- // if toExcel = false, export dbgrid contents to the Clipboard // if toExcel = true, export dbgrid to Microsoft Excel procedure ExportDBGrid(toExcel: Boolean); var bm: TBookmark; col, row: Integer; sline: String; mem: TMemo; ExcelApp: Variant; begin Screen.Cursor := crHourglass; DBGrid1.DataSource.DataSet.DisableControls; bm := DBGrid1.DataSource.DataSet.GetBookmark; DBGrid1.DataSource.DataSet.First; // create the Excel object if toExcel then begin ExcelApp := CreateOleObject('Excel.Application'); ExcelApp.WorkBooks.Add(xlWBatWorkSheet); ExcelApp.WorkBooks[1].WorkSheets[1].Name := 'Grid Data'; end; // First we send the data to a memo // works faster than doing it directly to Excel mem := TMemo.Create(Self); mem.Visible := false; mem.Parent := MainForm; mem.Clear; sline := ''; // add the info for the column names for col := 0 to DBGrid1.FieldCount-1 do sline := sline + DBGrid1.Fields[col].DisplayLabel + #9; mem.Lines.Add(sline); // get the data into the memo for row := 0 to DBGrid1.DataSource.DataSet.RecordCount-1 do begin sline := ''; for col := 0 to DBGrid1.FieldCount-1 do sline := sline + DBGrid1.Fields[col].AsString + #9; mem.Lines.Add(sline); DBGrid1.DataSource.DataSet.Next; end; // we copy the data to the clipboard mem.SelectAll; mem.CopyToClipboard; // if needed, send it to Excel // if not, we already have it in the clipboard if toExcel then begin ExcelApp.Workbooks[1].WorkSheets['Grid Data'].Paste; ExcelApp.Visible := true; end; FreeAndNil(mem); // FreeAndNil(ExcelApp); DBGrid1.DataSource.DataSet.GotoBookmark(bm); DBGrid1.DataSource.DataSet.FreeBookmark(bm); DBGrid1.DataSource.DataSet.EnableControls; Screen.Cursor := crDefault; end; ----------------------------------------------- 數(shù)據(jù)網(wǎng)格自動適應(yīng)寬度///////源代碼開始 uses Math; function DBGridRecordSize(mColumn: TColumn): Boolean; { 返回記錄數(shù)據(jù)網(wǎng)格列顯示最大寬度是否成功 } begin Result := False; if not Assigned(mColumn.Field) then Exit; mColumn.Field.Tag := Max(mColumn.Field.Tag, TDBGrid(mColumn.Grid).Canvas.TextWidth(mColumn.Field.DisplayText)); Result := True; end; { DBGridRecordSize } function DBGridAutoSize(mDBGrid: TDBGrid; mOffset: Integer = 5): Boolean; { 返回數(shù)據(jù)網(wǎng)格自動適應(yīng)寬度是否成功 } var I: Integer; begin Result := False; if not Assigned(mDBGrid) then Exit; if not Assigned(mDBGrid.DataSource) then Exit; if not Assigned(mDBGrid.DataSource.DataSet) then Exit; if not mDBGrid.DataSource.DataSet.Active then Exit; for I := 0 to mDBGrid.Columns.Count - 1 do begin if not mDBGrid.Columns[I].Visible then Continue; if Assigned(mDBGrid.Columns[I].Field) then mDBGrid.Columns[I].Width := Max(mDBGrid.Columns[I].Field.Tag, mDBGrid.Canvas.TextWidth(mDBGrid.Columns[I].Title.Caption)) + mOffset else mDBGrid.Columns[I].Width := mDBGrid.Canvas.TextWidth(mDBGrid.Columns[I].Title.Caption) + mOffset; mDBGrid.Refresh; end; Result := True; end; { DBGridAutoSize } ///////源代碼結(jié)束 ///////使用示例開始 procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin DBGridRecordSize(Column); end; procedure TForm1.Button1Click(Sender: TObject); begin DBGridAutoSize(DBGrid1); end; ///////使用示例結(jié)束 |
|