如何在DBGrid的每一行前加一个单选框?

zeroliu 2001-11-25 09:49:11

如何在DBGrid的每一行前加一个单选框,以表示本行已被选定?
...全文
212 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
fenglingdu 2002-01-11
  • 打赏
  • 举报
回复
学习。。。
Slash 2001-11-26
  • 打赏
  • 举报
回复
转载一篇给你,希望对你有帮助(如他人有转载需要,请保留作者名称,以示尊重,谢谢)

在DELPHI中利用API实现网格内组件的嵌入
河南金融管理干部学院计算机教研室 陈学军

Delphi中向TDBGrid添加组件是一件十分麻烦的事情。在这里向大家介绍一种利用WIN32 API函数在TDBGRID中嵌入CHECKBOX组件的方法。
TDBGrid部件是用于显示和编辑数据库表中的记录信息的重要部件,它是我们在程序设计过程当中要经常使用的、灵活地用于显示和编辑数据库表中的记录信息的一个强有力的工具。TDBGrid具有很多重要的属性,我们可以在程序设计阶段和程序运行过程中进行设置。TDBGrid部件的一些重要属性及其设置方法请参看联机帮助文件。TDBGrid部件中一些重要的属性是Option属性和DefaultDrawing属性,我们重点对两个属性进行阐述。
Options属性:它是TDBGrid部件的一个扩展属性,在程序设计阶段设置Options属性可以控制TDBGrid部件的显示特性和对事件的响应特性。
DefalultDrawing属性:该属性是布尔型属性,它用于控制网格中各网格单元的绘制方式。在缺省情况下,该属性的值为True,也就是说Delphi使用网格本身缺省的方法绘制网格中各网格单元,并填充各网格单元中的内容,各网格单元中的数据根据其对应的字段部件的DisplayFormat属性和EidtFormat属性进行显示和绘制。如果DefaulDrawing属性被设置为False时,Delphi不会自动地绘制网格中各网格单元和网格单元中的数据,用户必须自己为TDBGrid部件的OnDrawDataCell事件编写相应的程序用于绘制各网格单元和其中的数据。
首先,当一个布尔字段得到焦点时,TDBGrid.Options中的 gdEditing属性不能被设置成为可编辑模式。其次,TDBGrid.DefaultDrawing属性不要设置为FALSE,否则,就不能得到网格中画布属性的句柄。
程序设计开始时就应考虑:需要设定一变量来存储原始的 TDBGrid.Options的所有属性值。这样,当一boolean字段所在栏得到焦点时将要关闭TDBGrid.Options中gdEditing的可编辑模式。与此相对应,若该栏失去焦点时,就要重新恢复原始的 TDBGrid.Options的所有属性值。
在实例中布尔值的改变可以通过鼠标点击也可以敲打空格键,这样就需要触发TDBGrid.OnCellClick事件和TDBGrid.OnKeyDown事件。因为,这两个事件都是改变单元格中的逻辑字段的布尔值,为了减少代码的重复就创建一个私有过程(SaveBoolean;)完成逻辑值的输入,以后,在不同的事件中调用此过程即可。
在 TDBGrid.OnDrawColumnCell事件的处理上是整个程序的关键,在处理嵌入组件的显示上,并没有采取传统的方法:在表单上实际添加组件对象,然后对组件的位置属性与网格中单元格的位置属性进行调整,以达到嵌入的视觉效果。这种方法虽然可行但代码量大,实际运行控制性差。在这里而是充分利用WIN32 API函数:DrawFrameControl(),无须在表单中实际添加组件,因为此函数可以画出Checkbox组件。如何使用API函数:DrawFrameControl()是本程序技巧所在。
在TDBGrid.OnDrawColumnCell事件中会注意到:设定一个整型数组常数,这个返回的整数值是与布尔值相一致,如果字段是逻辑字段,只将其布尔值放入数组,提供给DrawFrameControl()函数中状态参数进行调用,就实现了Checkbox组件在网格中嵌入效果。
源代码如下:
type
TForm1 = class(TForm)
DataSource1: TDataSource;
Table1: TTable;
DBGrid1: TDBGrid;
procedure DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer;
Column: TColumn; State: TGridDrawState);
procedure DBGrid1ColEnter(Sender: TObject);
procedure DBGrid1ColExit(Sender: TObject);
procedure DBGrid1CellClick(Column: TColumn);
procedure DBGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
OriginalOptions : TDBGridOptions;
procedure SaveBoolean;
public
{ Public declarations }
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);
DrawFrameControl(DBGrid1.Canvas.Handle,
Rect,
DFC_BUTTON,
CtrlState[Column.Field.AsBoolean]);
end;
end;

procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
// 确保该栏是逻辑字段
if DBGrid1.SelectedField.DataType = ftBoolean then
begin
OriginalOptions := DBGrid1.Options;
DBGrid1.Options := DBGrid1.Options - [dgEditing];
end;
end;

procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
//确保该栏是逻辑字段
if DBGrid1.SelectedField.DataType = ftBoolean then
DBGrid1.Options := OriginalOptions;
end;

procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
//确保该栏是逻辑字段
if DBGrid1.SelectedField.DataType = ftBoolean then
SaveBoolean();
end;

procedure TForm1.DBGrid1KeyDown(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
//确保该栏是逻辑字段和空格键在键盘中被点击
if ( Key = VK_SPACE ) and
( DBGrid1.SelectedField.DataType = ftBoolean ) then
SaveBoolean();
end;

procedure TForm1.SaveBoolean;
begin
DBGrid1.SelectedField.Dataset.Edit;
DBGrid1.SelectedField.AsBoolean :=
not DBGrid1.SelectedField.AsBoolean;
DBGrid1.SelectedField.Dataset.Post;
end;
jerfly 2001-11-26
  • 打赏
  • 举报
回复
也给我一个
Email:Jerfly@sohu.com
ggyy 2001-11-26
  • 打赏
  • 举报
回复
我觉得我的想法能做到,不过外观不好看!!11
欢迎大家指出错误:)
xiaowen72 2001-11-26
  • 打赏
  • 举报
回复
To albert():
老兄,也给我一个,好吗?
xiaowen72@263.net

我也想学习一下.谢了
cwpower 2001-11-26
  • 打赏
  • 举报
回复
我前两天也在想这个功能的实现,但实在没有想出什么好方法,最后,我做了一个浮动的窗口,DBgrid里的数据被双击选中后便被添加到这个浮动的窗口中,然后再在这个窗口做其他功能。

如果你实现了你的功能,不妨帖出来说说啊
天涯浪子 2001-11-26
  • 打赏
  • 举报
回复
To albert():
老兄,也给我一个,好吗?我也正好要用到
ljwmail03@sina.com
hellowbh 2001-11-26
  • 打赏
  • 举报
回复
关注
albert 2001-11-26
  • 打赏
  • 举报
回复
我手头刚好有这样一个DEMO,怎么发给你?
AlbertZhang@163.net
zeroliu 2001-11-26
  • 打赏
  • 举报
回复

谢谢!
我的E-mail: zeroliu@163.com
ggyy 2001-11-25
  • 打赏
  • 举报
回复
1,如果不实现多项选则的话,不必要!
2,为每一行前面加checkbutton,然后当光标在哪行的时候就把前面打勾,离开的时候去掉(此方法
我没用过,应该可以的):)
zeroliu 2001-11-25
  • 打赏
  • 举报
回复
对不起,以上选项里面没有我要的设置。

再问一句:如果DBGrid无法此功能,又该如何实现?
ggyy 2001-11-25
  • 打赏
  • 举报
回复
Description

Set Options to include the desired properties for the data-aware grid. Options is a set drawn from the following values:

Value Meaning

dgEditing The user can edit data using the grid. dgEditing is ignored if Options includes dgRowSelect.
dgAlwaysShowEditor The grid is always in edit mode. That is, the user does not have to press Enter or F2 before editing the contents of a cell. dgAlwaysShowEditor does nothing unless dgEditing is also included in Options. dgAlwaysShowEditor is ignored if Options includes dgRowSelect.
dgTitles Titles appear at the top of the columns in the grid.
dgIndicator A small pointer appears in the first column to indicate which row is current.

dgColumnResize Columns that are bound to fields can be resized or moved.
dgColLines Lines appear between columns in the grid.
dgRowLines Lines appear between the rows of the grid.
dgTabs The user can navigate through the grid using the Tab and Shift+Tab keys.
dgRowSelect The user can select an entire row, as well as selecting individual cells. If Options includes dgRowSelect, dgEditing and dgAlwaysShowEditor are ignored.
dgAlwaysShowSelection The selected cell displays the focus rectangle even when the grid does not have focus.

dgConfirmDelete A message box appears, asking for confirmation, when the user types Ctrl+Delete to delete a row in the grid.
dgCancelOnExit When the user exits the grid from an inserted record to which the user made no modifications, the inserted record is not posted to the dataset. This prevents the inadvertent posting of empty records.
dgMultiSelect More than one row in the grid can be selected at a time.
zeroliu 2001-11-25
  • 打赏
  • 举报
回复
应该如何设置?
ggyy 2001-11-25
  • 打赏
  • 举报
回复
DBGrid好像有这个style

13,826

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧