Delphi DBGrid中的复选框

Delphi DBGrid中的复选框,delphi,grid,tcheckbox,Delphi,Grid,Tcheckbox,我的问题是如何在Delphi7中的dbgrid中设置一列,该列将带有复选框项 提前谢谢。好的 我用这篇文章来解决我的问题。好的,但问题是它没有按应有的方式工作。所以我改变了代码中的逻辑。并通过将dbgrid中选定的行保存在列表中来实现它。如果使用TClientDataset+TDatasetProvider+TDataset,则可以在数据数组变量到达clientdataset之前对其进行操作,并包含一个不可更新的布尔字段 完成后,只需使用OnDrawColumnCell事件在网格上绘制即可。在这

我的问题是如何在Delphi7中的dbgrid中设置一列,该列将带有复选框项

提前谢谢。

好的
我用这篇文章来解决我的问题。好的,但问题是它没有按应有的方式工作。所以我改变了代码中的逻辑。并通过将dbgrid中选定的行保存在列表中来实现它。

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


完成后,只需使用OnDrawColumnCell事件在网格上绘制即可。在这里,我没有使用复选框,只是使用了一个位图(当用户单击它时,它会变为选中/未选中)。

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

在单位的“专用”部分中,声明保留网格选项的全局设置。在输入复选框列时临时禁用文本编辑后,它将用于恢复,因为这可能是Jordan Borisovin提到的关于delphi.about.com文章的小错误之一

在OnCellClick事件中,如果字段为布尔值,则切换并将更改后放到数据库中

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

现在,在新部件中,在布尔列中禁用单元格编辑。在OnClenter和OnClexit事件上:

更重要的是,使用空格键切换复选框


就这样

请原谅我将此作为答案发布,我还没有50%的声誉来添加评论

这个问题的答案非常接近于罕见的解决方案(就像在实际工作中一样),除了一个出现bug的用例

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

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

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

就这样

您好,您是否尝试过学习教程?@TLama,如果您将您的评论作为答案发布,我会投赞成票。@TLama,完美链接(不将其作为答案的好选择)。PA,没有其他内容的外部网站链接(或者如果外部链接不起作用,则内容将毫无意义)在这里是不可接受的答案。答案应该是独立的,并且在没有任何其他内容的情况下仍然有用。特拉玛做了一个完美的决定。只有外部链接的答案通常会很快被标记和删除。是的,我找到了这个链接并尝试实现它。但还有一点错误。所以我改变了我在源代码中的逻辑。不过先谢谢你。您应该将其作为答案发布,我会将其设置为一个。@Jordan请不要。您最好自己给出答案,解释您遇到的错误并提供自己的解决方案。你可能会从中抽出一些代表和/或徽章。嗯,这不符合回答的条件,而是对主要问题的编辑。也许你想在这里加入一些代码来启发你如何做事……这是对我有用的答案。我发现的唯一问题是复选框字段是否是网格中的第一列。在这种情况下,GridOriginalOptions不会被初始化。很容易修复,只需向表单的Create方法添加GridOriginalOptions:=DBGrid1.Options。
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;
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;
procedure TForm1.DBGrid1Enter(Sender: TObject);
begin
  DBGrid1ColEnter(Sender);
end;