如何让我的所有网格在我的表单中看起来都一样? 我想实现一个必须应用于我的项目的所有网格的替代行颜色。是否可以不为每个网格添加相同的DrawColumnCell事件代码? 我想避免为每个网格添加相同的代码。我在我的项目中有30个网格,并乘以13行代码,它只是为我的项目添加了许多代码行,使其“不友好”。 我正在寻找一种解决方案,只能为项目添加13行代码,而不是390行。
我的格式代码如下所示(例如):
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上寻找解决方案
我试图在每个表单中破解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;
我可以这样做但我无法访问发件人,因此我可以访问数据集并知道哪个记录要着色而哪些记录没有(奇数和偶数)。 这是一个糟糕的方法,因为我必须在每个表格上都这样做,所以这不是一个真正的解决方案
有什么想法吗?
谢谢
答案 0 :(得分: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数据集通常不具有此值。访问它(特别是在大型或基于查询的数据集上)会对您的应用程序造成重大性能损失。当然,不使用它意味着您无法使用此解决方案。一个更好的解决方案是使用数据集的BeforeScroll或AfterScroll事件的处理程序来切换此代码可用的布尔值,并使用该处理程序而不是Odd(RecNo)
的测试,或者数据集仅用于显示DBGrid,使用TDataSet.Tag
事件中的AfterScroll
来使用
OddRow := Boolean(DataSet.Tag);
DataSet.Tag := Ord(not OddRow);
将DBGrids添加到数据模块的uses子句中,并在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;
答案 1 :(得分:1)
这适用于Delphi 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;