本文介绍了Delphi DBGrid项目中所有DBGrid的备用行颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使所有表格在整个表格中看起来都一样?
我想实现必须在项目的所有网格上应用的备用行颜色。是否可以为每个网格不添加相同的DrawColumnCell事件代码?
我想避免为每个网格添加相同的代码。我的项目中有30个网格,再乘以13行代码,这只会给我的项目增加很多代码行,使其不友好。
我正在寻找一种解决方案,该解决方案只会向项目中添加13行代码,而不是390行。

How can I make all my grids look the same way all over my forms?I want to implement an alternate row color that must be applied on all grids of my project. Is it possible without adding the same DrawColumnCell event code for every grid?I want to avoid adding the same code for each of my grids. I have like 30 grids in my project and multiplied by 13 rows of code it just adds a lot of code lines to my project making it "unfriendly".I am looking for a solution that will only add 13 lines of code to the project, not 390 lines.

我的格式设置代码如下(例如):

My formatting code looks like this (for example):

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,但是我不知道确切的样子在Google上解决此问题的方法

Probably I would need to extend the DBGrid somehow, but I do not know exactly how nor how to look for a solution for this on google

我试图破解每种表单内的DBGRid,如下所示:

I tried to hack the DBGRid inside each form like this:

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;

我可以执行此操作,但无法访问发送者,因此可以访问数据集并知道哪个记录颜色,而不是(奇数和偶数)。
无论如何这都是一种差劲的方法,因为我必须在每种表单上都这样做,所以它并不是真正的解决方案

I can do this but I cannot access the sender, so I can access the dataset and know which record to color and which not (odd and even).And this is a poor approach anyways since I will have to do it on every form, so it's not really a solution

有什么想法吗?

谢谢

推荐答案

如果在数据模块中放入类似内容,然后分配到每个DBGrid的 OnDrawColumnCell ,它似乎都可以工作(请参阅后面的注释):

If you put something like this in your datamodule, and assign it to the OnDrawColumnCell of every DBGrid, it seems to work (see notes that follow):

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后数据集通常没有此值。访问它(尤其是在大型数据集或基于查询的数据集上)会严重影响应用程序的性能。当然,不使用它意味着您不能使用此解决方案。更好的解决方案是对数据集的BeforeScroll或AfterScroll事件使用处理程序,该处理程序切换可用于此代码的布尔值,并代替 Odd(RecNo),或者如果数据集仅用于显示在DBGrid中,请在 AfterScroll 事件中使用 TDataSet.Tag

  • First, you should avoid using TDataSet.RecNo in the first place, because post-BDE datasets don't typically have this value available. Accessing it (particularly on large or query-based datasets) causes a major performance hit to your application. Of course, not using it means that you can't use this solution. A better solution would be to use a handler for the dataset's BeforeScroll or AfterScroll event that toggled a boolean available to this code instead, and use that instead of the test for Odd(RecNo), or if the dataset is only used for displaying in the DBGrid, use the TDataSet.Tag in the AfterScroll event to track the row's odd/even state using

OddRow := Boolean(DataSet.Tag);
DataSet.Tag := Ord(not OddRow);


  • 将DBGrids添加到数据模块的uses子句中,并在已发布部分,以便使用该数据模块的所有单元均可使用。然后,您可以照常从这些单元中在对象检查器事件选项卡中对其进行分配。

  • Add DBGrids to the uses clause of your datamodule, and manually declare the above event in the published section so that it's available to all units that use the datamodule. You can then assign it in the Object Inspector Events tab as usual from those units.

    这不能正确处理 TGridDrawState (您的初始代码也没有)。您需要为此自己添加处理,因为这不是您在此处所要求的。

    This does not properly handle the TGridDrawState (nor does your initial code). You'll need to add handling for that yourself, as that wasn't what you asked here.

    取决于您要为奇数和偶数行使用哪种颜色,您可能想反转 RowColors 中的颜色顺序。

    Depending on which color you want for odd and even rows, you may want to reverse the order of the colors in RowColors.

    我更喜欢重复的类型转换这样很清楚代码在做什么。如果让您感到困扰,您只需声明一个局部变量即可:

    I prefer the repeated typecasts so that it's clear what the code is doing. If it bothers you, you can simply declare a local variable instead:

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


  • 这篇关于Delphi DBGrid项目中所有DBGrid的备用行颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-24 10:15