DBGrid中的CheckBox

时间:2012-01-26 14:43:36

标签: delphi grid tcheckbox

我的问题是如何在Delphi 7中的dbgrid中设置一个列,其中包含一个复选框项。

提前致谢。

4 个答案:

答案 0 :(得分:10)

我测试的最简单,最完整的方法如下:

在您设备的私有部分中,声明一个全局用于保留网格选项。在输入复选框列时临时禁用文本编辑后,它将用于恢复 - 因为这可能是Jordan Borisovin提到的关于delphi.about.com文章

的一个小错误
private      
  GridOriginalOptions : TDBGridOptions;

在OnCellClick事件中,如果field是boolean,则切换并将更改发布到数据库

procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin  
  if (Column.Field.DataType=ftBoolean) then
  begin      
    Column.Grid.DataSource.DataSet.Edit;
    Column.Field.Value:= not Column.Field.AsBoolean;
    Column.Grid.DataSource.DataSet.Post;   
  end;
end;

绘制网格布尔字段的复选框

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; 
  DataCol: Integer;      Column: TColumn; State: TGridDrawState);
const
   CtrlState: array[Boolean] of integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED) ;
begin
  if (Column.Field.DataType=ftBoolean) then
  begin
    DBGrid1.Canvas.FillRect(Rect) ;
    if (VarIsNull(Column.Field.Value)) then
      DrawFrameControl(DBGrid1.Canvas.Handle,Rect, DFC_BUTTON, DFCS_BUTTONCHECK or DFCS_INACTIVE)
    else
      DrawFrameControl(DBGrid1.Canvas.Handle,Rect, DFC_BUTTON, CtrlState[Column.Field.AsBoolean]); 
  end;
end;

现在是新的部分,在布尔列中禁用单元格编辑。在OnColEnter和OnColExit事件上:

procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
  if Self.DBGrid1.SelectedField.DataType = ftBoolean then
  begin
    Self.GridOriginalOptions := Self.DBGrid1.Options;
    Self.DBGrid1.Options := Self.DBGrid1.Options - [dgEditing];
  end;
end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
  if Self.DBGrid1.SelectedField.DataType = ftBoolean then
    Self.DBGrid1.Options := Self.GridOriginalOptions;
end;

更多,处理空格键以切换复选框

procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState);
begin
  if ((Self.DBGrid1.SelectedField.DataType = ftBoolean) and (key = VK_SPACE)) then
  begin
    Self.DBGrid1.DataSource.DataSet.Edit;
    Self.DBGrid1.SelectedField.Value:= not Self.DBGrid1.SelectedField.AsBoolean;
    Self.DBGrid1.DataSource.DataSet.Post;   
  end;      
end;

就是这样!

答案 1 :(得分:1)

如果您正在使用TClientDataset + TDatasetProvider + TDataset,则可以在数据数组变量到达clientdataset之前对其进行操作,并包含不可更新的布尔字段。

完成后,您只需使用OnDrawColumnCell事件在网格上绘图。这里我没有使用CheckBox而只是一个位图(当用户点击它时会改为选中/未选中)。

答案 2 :(得分:1)

请原谅我发布此答案,我还没有50个声誉来添加评论。

Mihai MATEI的答案非常接近稀有(如实际工作中)解决方案,除了它出现错误的用例。

每当用户对网格的第一个操作是单击复选框时,第一次单击将起作用,但第二次将显示底层DBGrid编辑器。

这是因为需要初始化“GridOriginalOptionsmechan”机制。 为此,只需在网格的OnEnter事件中添加以下代码:

procedure TForm1.DBGrid1Enter(Sender: TObject);
begin
  DBGrid1ColEnter(Sender);
end;

就是这样!

答案 3 :(得分:-1)

行 我使用this文章解决了我的问题。好的但问题是它不应该如何工作。所以我改变了代码中的逻辑。并通过在列表中保存dbgrid中的选定行来实现它。