这是一个在dbgrid中加入checkbox的例子,给你作参考。
Delphi中向TDBGrid添加组件是一件十分麻烦的事情。笔者在这里向大家介绍一种利用WIN32 API函数在TDBGRID中嵌入CHECKBOX组件的方法。 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;
Delphi中向TDBGrid添加组件是一件十分麻烦的事情。笔者在这里向大家介绍一种利用WIN32 API函数在TDBGRID中嵌入CHECKBOX组件的方法。 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;
解决方案 »
- delphi exe文件名
- 请问delphi ScrollBoxShow控件在哪个项?
- 如何在delphi本地系统中嵌入IE程序?
- 这个动态文件该如何调用?急!!!
- 加分http://expert.csdn.net/Expert/topic/2312/2312977.xml?temp=.3351099,
- 心情不爽来放点血(3)
- 插入SQL语句查错,在线等待。
- fastreport可以实现套打吗?可以根据结果值改变颜色吗?
- 谁能帮我看看哪里出错了(一个SQL语句的问题),急!在线等待!
- 各位DELPHI的哥们,我因为工作关系要从VB转到DELPHI了,下面是我的几个问题
- 高分求书:用DELPHI搞数据库的书!
- 如何在delphi用excel编的数据库
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids;type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Edit1: TEdit;
ComboBox1:TComboBox;
procedure FormCreate(Sender: TObject);
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure Edit1Change(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
x,y:integer;implementation{$R *.DFM}procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Visible:=False;
ComboBox1.Visible:=False;
end;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
x:=aCol;
y:=aRow;
if (gdFocused in State) then
begin
if aCol = 1 then
begin
Edit1.Text := StringGrid1.Cells[x,y];
Edit1.Left := Rect.Left + StringGrid1.Left + 2;
Edit1.Top := Rect.Top + StringGrid1.top + 2;
Edit1.Width := Rect.Right - Rect.Left;
Edit1.Height := Rect.Bottom - Rect.Top;
Edit1.Visible := True;
end; if aCol = 0 then
begin
ComboBox1.Text := StringGrid1.Cells[x,y];
ComboBox1.Left := Rect.Left + StringGrid1.Left + 2;
ComboBox1.Top := Rect.Top + StringGrid1.top + 2;
ComboBox1.Width := Rect.Right - Rect.Left;
ComboBox1.Height := Rect.Bottom - Rect.Top;
ComboBox1.Visible := True;
end;
end else
begin
Edit1.Visible:=False;
ComboBox1.Visible:=False;
end;
end;procedure TForm1.Edit1Change(Sender: TObject);
begin
//判断数据有效性
StringGrid1.Cells[x,y]:=Edit1.Text;
end;procedure TForm1.ComboBox1Change(Sender: TObject);
begin
StringGrid1.Cells[x,y]:=ComboBox1.Text;
end;end.
新建一个工程,然后放上一个stringGrid,注意调整每行的高度。
放上一个ComboBox,然后将其Visible属性社为false;
然后粘贴我下面的代码,保证可以运行,我刚刚调试通过的。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
ComboBox1: TComboBox;
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure FormCreate(Sender: TObject);
procedure ComboBox1Change(Sender: TObject);
private
{ Private declarations }
nowCol,nowRow:integer;
cbAppear:boolean;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
var
i,w,h:integer;
begin
w:=0;
h:=0;
for i:= 0 to acol-1 do
w:=w+stringgrid1.ColWidths[i]; for i:=0 to arow-1 do
h:=h+stringgrid1.RowHeights[i]; w:=w+stringgrid1.Left;
h:=h+stringgrid1.Top;
comboBox1.Left :=w+6;
combobox1.Top :=h+2;
combobox1.Width := stringgrid1.ColWidths[acol];
combobox1.Height :=stringgrid1.RowHeights[arow];
comboBox1.Text :='';
combobox1.Visible :=true;
nowRow:=aRow;
nowcol:=aCol;
cbAppear:=true;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
comboBox1.Items.Add('美国');
comboBox1.Items.Add('中国');
comboBox1.items.Add('英国');
end;procedure TForm1.ComboBox1Change(Sender: TObject);
begin
if cbAppear then
begin
stringgrid1.Cells[nowCol,nowRow]:=combobox1.Text ;
combobox1.Visible :=false;
cbAppear:=false;
end;
end;end.
procedure TFrmadd.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if (gdfocused in state) or (gdselected in state) or (gdfixed in state)then
begin
if (dbgrid1.SelectedIndex=7) then
begin
combobox1.Left:=rect.Left+dbgrid1.Left+1;
combobox1.Top:=rect.top+dbgrid1.top+1;
combobox1.Width:=rect.Right-rect.left+1;
combobox1.Height:=rect.bottom-rect.top+1;
combobox1.Visible:=true
end;
end;
end;