继续本question及其非常有用的答案:我在 big 项目中实现了Ken的答案的变体,其中我有类似的代码以多种形式出现。但我注意到我也有一些使用DrawColumnCell处理程序的表单如下
procedure TEditDocket.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
var
DrawRect: TRect;
begin
if column.Index = 3 then
begin
DrawRect:= Rect;
drawrect.left:= rect.left + 24;
InflateRect (DrawRect, -1, -1);
dbgrid1.Canvas.FillRect (Rect);
DrawFrameControl (dbgrid1.Canvas.Handle, DrawRect, DFC_BUTTON,
ISChecked[Column.Field.AsInteger]);
end
else dbgrid1.DefaultDrawColumnCell (Rect, DataCol, Column, State);
end;
如何将上述代码与一般的OnDrawColumnCell处理程序结合起来?是否可以使用额外的参数定义通用处理程序(这将是列索引;如果它是-1,那么上面的代码将不会执行)?我如何将这样的参数传递给处理程序?
答案 0 :(得分:1)
我看到(从评论链中)你想要调用泛型或(在某些情况下)也调用复选框绘图的代码。
通用的OnDrawColumnCell处理程序处理单元格的背景颜色。如何扩展它以创建一个处理程序,它也将在需要时绘制复选框?顺便说一下,通用代码必须在复选框代码之前调用,而不是在。
之后调用
这实际上非常简单。使用正确的签名(通用签名和复选框1)定义两种方法(代码未经测试!)。但是,只将通用事件连接到TDBGrid.OnDrawColumnCell
事件 - 如果需要,将复选一个复选框:
// Generic (from my other post) - notice method name has changed
procedure TDataModule1.GenericDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
RowColors: array[Boolean] of TColor = (clSilver, clDkGray);
var
OddRow: Boolean;
Grid: TDBGrid;
begin
if (Sender is TDBGrid) then
begin
Grid := TDBGrid(Sender);
OddRow := Odd(Grid.DataSource.DataSet.RecNo);
Grid.Canvas.Brush.Color := RowColors[OddRow];
Grid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
// If you want the check box code to only run for a single grid,
// you can add that check here using something like
//
// if (Column.Index = 3) and (Sender = DBGrid1) then
//
if (Column.Index = 3) then //
CheckBoxDrawColumCell(Sender, Rect, DataCol, Column, State)
end;
end;
// Checkbox (from yours) - again, notice method name change.
procedure TEditDocket.CheckBoxDrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
DrawRect: TRect;
Grid: TDBGrid;
begin
// Don't use DBGrid1, because it makes the code specific to a single grid.
// If you need it for that, make sure this code only gets called for that
// grid instead in the generic handler; you can then use it for another
// grid later (or a different one) without breaking any code
if column.Index = 3 then
begin
Grid := TDBGrid(Sender);
DrawRect:= Rect;
Drawrect.Left := Rect.Left + 24;
InflateRect (DrawRect, -1, -1);
Grid.Canvas.FillRect (Rect);
DrawFrameControl (Grid.Canvas.Handle, DrawRect, DFC_BUTTON,
ISChecked[Column.Field.AsInteger]); // Don't know what ISChecked is
end;
// The below should no longer be needed, because DefaultDrawColumnCell has
// been called by the generic handler already.
//
// else
// Grid.DefaultDrawColumnCell (Rect, DataCol, Column, State);
end;
在看到您对Sertac的评论之后:
在一个网格中,它可以是第3列,而它可以是第4列,需要将其绘制为复选框。
我在上面的代码中提供了一种解决方法(请参阅GenericDrawColumnCell
中的注释)。另一种方法(假设每个网格中只有一列需要复选框)是指示包含TDBGrid.Tag
属性中的复选框的列:
if (Column.Index = Grid.Tag) then
答案 1 :(得分:1)
独立地,我使用网格的'tag'属性达到了以下答案。
在客户端表单中,我写了
dbGrid1.OnDrawColumnCell:= dm.DBGrid1DrawColumnCell;
dbGrid1.tag:= 3; // column with checkbox
dbGrid2.OnDrawColumnCell:= dm.DBGrid1DrawColumnCell;
dbGrid2.tag:= $23; // both columns 2 and 3 are checkboxes
默认处理程序现在是
procedure TDm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
IsChecked : array[0..1] of Integer =
(DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
DrawRect: TRect;
tag: integer;
cols: set of byte;
begin
if sender is TDBGrid then
begin
tag:= TDBGrid (sender).tag;
if (THackDBGrid (sender).DataLink.ActiveRecord + 1 = THackDBGrid (sender).Row)
or (gdFocused in State) or (gdSelected in State) then
with TDBGrid (sender) do
begin
canvas.Brush.Color:= clMoneyGreen;
canvas.font.color:= clNavy;
end;
cols:= [];
while tag > 0 do
begin
cols:= cols + [tag mod 16];
tag:= tag div 16
end;
if column.Index in cols then
begin
DrawRect:= Rect;
drawrect.left:= rect.left + 24;
InflateRect (DrawRect, -1, -1);
TDBGrid (sender).Canvas.FillRect (Rect);
DrawFrameControl (TDBGrid (sender).Canvas.Handle, DrawRect, DFC_BUTTON,
ISChecked[Column.Field.AsInteger]);
end
else
begin
TDBGrid (sender).DefaultDrawColumnCell (Rect, DataCol, Column, State);
end;
end;
end;
这意味着第0列绝不能是复选框。使用集合允许网格中最多四列为复选框。