2014-02-28 159 views
2

如何使我的所有網格在我的表單中看起來都一樣? 我想實現一個備用行顏色,必須應用於我的項目的所有網格。沒有爲每個網格添加相同的DrawColumnCell事件代碼是否可能? 我想避免爲每個網格添加相同的代碼。我在我的項目中使用了30個網格,並乘以13行代碼,它只是將很多代碼行添加到我的項目中,使其「不友好」。 我正在尋找一種解決方案,只能將13行代碼添加到項目中,而不是390行。Delphi DBGrid項目中所有DBGrid的交替行顏色

我格式化代碼看起來像這樣(例如):

procedure TDBGrid.DBGrid1DrawColumnCell(Sender: TObject;const Rect: TRect;DataCol: Integer;Column: TColumn;State: TGridDrawState) ; 
var 
    grid : TDBGrid; 
    row : integer; 
begin 
    grid := sender as TDBGrid; 
    row := grid.DataSource.DataSet.RecNo; 
    if Odd(row) then 
    grid.Canvas.Brush.Color := clSilver 
    else 
    grid.Canvas.Brush.Color := clDkGray; 
    grid.DefaultDrawColumnCell(Rect, DataCol, Column, State) ; 
end; 

也許我需要以某種方式延長DBGrid的,但我不知道究竟怎麼也不知道怎樣去尋找一個解決方案,這對谷歌

我試圖破解DBGRID每個窗體像這裏面:

type 
    TDBGrid = class(DBGrids.TDBGrid) 
    protected 
    procedure DrawColumnCell(const Rect: TRect; DataCol: Integer;Column: TColumn; State: TGridDrawState); override; 
    end; 
... 
procedure TDBGrid.DrawColumnCell(const Rect: TRect; DataCol: Integer;Column: TColumn; State: TGridDrawState) ; 
var 
     grid : TDBGrid; 
     row : integer; 
begin 
     row := 2;//grid.DataSource.DataSet.RecNo; 
     if Odd(row) then 
     Canvas.Brush.Color := clSilver 
     else 
     Canvas.Brush.Color := clDkGray; 
     DefaultDrawColumnCell(Rect, DataCol, Column, State) ; 
end; 

我能做到這一點,但我不能訪問發件人,這樣我就可以訪問數據集並知道WHI ch記錄顏色,哪些不是(奇數和偶數)。 反正這是一個糟糕的方法,因爲我將不得不在每一個表格上都這樣做,所以它不是一個真正的解決方案

任何想法?

謝謝

回答

3

如果你把這樣的事情在你的數據模塊,並將其分配給每一個DBGrid的OnDrawColumnCell,似乎工作(見下面說明):

procedure TDataModule1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; 
    DataCol: Integer; Column: TColumn; State: TGridDrawState); 
const 
    RowColors: array[Boolean] of TColor = (clSilver, clDkGray); 
var 
    OddRow: Boolean; 
begin 
    // Safety check, although it really isn't needed; no other control accepts 
    // this event handler definition, AFAIK, so the only way to call it with the 
    // wrong Sender type would be to do so in your own code manually. In my own 
    // code, I'd simply leave out the check and let the exception happen; if I 
    // was stupid enough to do so, I'd want my hand slapped rudely. 
    if (Sender is TDBGrid) then 
    begin 
    OddRow := Odd(TDBGrid(Sender).DataSource.DataSet.RecNo); 
    TDBGrid(Sender).Canvas.Brush.Color := RowColors[OddRow]; 
    TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State); 
    end; 
end; 

一對夫婦筆記:

  • 首先,你應該避免在首位使用TDataSet.RecNo,因爲BDE後的數據集通常不具有該值的vailable。訪問它(特別是在大型數據集或基於查詢的數據集上)會對應用程序造成重大性能下降。當然,不使用它意味着你不能使用這個解決方案。一個更好的解決方案是使用數據集的BeforeScroll或AfterScroll事件的處理程序來代替此代碼可用的布爾值,並使用該代替Odd(RecNo)的測試,或者如果數據集僅用於在DBGrid中顯示,請使用在TDataSet.TagAfterScroll事件中使用

    OddRow := Boolean(DataSet.Tag); 
    DataSet.Tag := Ord(not OddRow); 
    
  • 添加DBGrids到您的數據模塊的使用條款來跟蹤該行的奇/偶狀態,並手動聲明中published部分上面的事件,以便它適用於所有單位使用數據模塊。然後,您可以像往常一樣從這些單元中將其分配到「對象檢查器事件」選項卡中。

  • 這沒有正確處理TGridDrawState(您的初始代碼也是如此)。你需要自己添加處理,因爲這不是你在這裏問的。

  • 根據您想要的奇數行和偶數行的顏色,您可能想要顛倒RowColors中的顏色順序。

  • 我更喜歡重複的類型轉換,這樣就很清楚代碼在做什麼。如果你煩惱,你可以簡單地聲明,而不是一個局部變量:

    var 
        OddRow: Boolean; 
        Grid: TDBGrid; 
    begin 
        if (Sender is TDBGrid) then 
        begin 
        Grid := TDBGrid(Sender); 
        OddRow := Odd(Grid.DataSource.DataSet.RecNo); 
        ... 
        end; 
    end; 
    
0

這適用於德爾福XE7

type 
    TDBGrid=Class(Vcl.DBGrids.TDBGrid) 
    procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL; 
    end; 

procedure TDBGrid.WMVScroll(var Message: TWMVScroll); 
begin 
    Self.Invalidate; 
    inherited; 
end; 

procedure TForm1. DBGrid1MouseWheel(Sender: TObject; Shift: TShiftState; 
    WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); 
begin 
    if Sender is TDBGrid then 
    (Sender as TDBGrid).Invalidate; 
end; 

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; 
    DataCol: Integer; Column: TColumn; State: TGridDrawState); 
const 
    MyRowColors : array[Boolean] of TColor = (clLime, clMoneyGreen); 
var 
    RowNo : Integer; 
    OddRow : Boolean; 
    S  : string; 
begin 
    if Sender is TDBGrid then begin 
    with (Sender as TDBGrid) do begin 
     if (gdSelected in State) then begin 
     // Farbe für die Zelle mit dem Focus 
     // color of the focused row 
     Canvas.Brush.Color := clblue; 
     end 
     else begin 
     // count := trunc((Sender as TDBGrid).Height div (Rect.Bottom - Rect.Top)); 
     // RowNo := (Sender as TDBGrid).Height div Rect.Top; 
     RowNo := Rect.Top div (Rect.Bottom - Rect.Top); 
     OddRow := Odd(RowNo); 
     Canvas.Brush.Color := MyRowColors[OddRow]; 

     // Font-Farbe immer schwarz 
     // font color always black 
     Canvas.Font.Color := clBlack; 
     Canvas.FillRect(Rect); 
     // Denn Text in der Zelle ausgeben 
     // manualy output the text 
     if Column.Field <> nil then begin 
      S := Column.Field.AsString; 
      Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, S); 
      // Canvas.TextOut(Rect.Left + 2, Rect.Top + 1, 'Column.Field.AsString'); 
     end; 
     end; 
    end 
    end; 
end;