dbgrid每一行加选择框 使用dbgrid增加一列类似checkbox的控件,可以用鼠标来选择该行是否被选中,可以多选 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 可以在DBGrid的后台DataSet中增加一列是ftBoolean类型的列 也就是在query里手动增加!Boolean类型的列 procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);beginend; 与数据库无关,因为楼主仅仅用这个checkbox表示改行是否被选中而已。在DBGrid的onDrawColumnCell中编写代码,给出示例,很简单需要你自己去发挥,只是给个思路 procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); var ck:Tcheckbox; begin if DataCol=0 then begin ck:=Tcheckbox.Create(self); ck.Parent:=self; ck.Width:=14; ck.Height:=14; ck.Left:=rect.Left+dbgrid1.Left+2; ck.Top:=rect.Top+dbgrid1.Top+2; end; end; 楼上创建CheckBox的做法是对的。不过,最好的思路还是要在数据表里增加一个布尔字段,然后用DBCheckBox与它关联,而不是CheckBox。(至于在DBGrid里嵌入DBCheckBox的方法,可以参考楼上,如果希望更详细,可以参考:http://topic.csdn.net/t/20021118/16/1186480.html) 如果就是不希望在数据表里增加一个布尔字段,就是想用CheckBox,那么,楼上的方法虽然能实现“嵌入”,但仅仅是“显示了CheckBox”,要想让它发挥作用(比如:取得当前记录的Checked状态),还要费点功夫。下面是我的测试代码:unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, DB, Grids, DBGrids, DBTables;type TForm1 = class(TForm) Table1: TTable; //这里用一个Table做测试。用其他的DataSet,如Query、ADOQuery等一样 DBGrid1: TDBGrid; DataSource1: TDataSource;//DataSource1如果换名字,下面的代码要随之更换 Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure ChkOnClick(Sender: TObject); //注意 end;var Form1: TForm1; ChksState : array of boolean; //全程数组,存放每条记录的CheckBox状态implementation{$R *.dfm}procedure TForm1.ChkOnClick(Sender: TObject); //所有CheckBox的Click事件begin if TCheckBox(Sender).Checked then ChksState[DataSource1.DataSet.RecNo-1] := true else ChksState[DataSource1.DataSet.RecNo-1] := false;end;procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);var Chk : TCheckBox;begin if (TDBGrid(Sender).DataSource.DataSet.Active) and (DataCol = 0) then begin Chk := TCheckBox.Create(self); Chk.Left := Rect.Left + TDBGrid(Sender).Left + 2; Chk.Top := Rect.Top + TDBGrid(Sender).top + 2; Chk.Height := Rect.Bottom - Rect.Top - 2; Chk.Width := Chk.Height; Chk.Color := clWhite; if ChksState[TDBGrid(Sender).DataSource.DataSet.RecNo-1] then Chk.Checked := true else Chk.Checked := false; Chk.OnClick := ChkOnClick; //注意 Chk.Parent := Self; Chk.Visible := true; end;end;procedure TForm1.Button1Click(Sender: TObject); //打开数据源并构建DBGridvar I : integer;begin with DBGrid1 do begin DataSource := DataSource1; DataSource.DataSet.Open; SetLength(ChksState,DataSource.DataSet.RecordCount); for I := 0 to DataSource.DataSet.FieldCount do Columns.Add; Columns[0].Title.Caption := 'Check'; for I := 1 to DataSource.DataSet.FieldCount do begin Columns[I].Field := DataSource.DataSet.Fields[I-1]; Columns[I].Title.Caption := 'Field_' + IntToStr(I); end; end;end;procedure TForm1.Button2Click(Sender: TObject); //测试begin if ChksState[DataSource1.DataSet.RecNo-1] then showmessage('当前记录状态= 选中!') else showmessage('当前记录 未选中');end;procedure TForm1.FormCreate(Sender: TObject);begin Table1.Close; DataSource1.DataSet := Table1;end;end. 在这个测试里,我用了一个Table,其DataBaseName和TableName属性,楼主自己设置。在测试效果按钮Button2里,写出了调用Checked状态的方法:那就是通过DataSet.RecNo对应的ChksState数组元素,来知道该记录是否选中。 这仅是一个演示代码。可以看出,劳心费力绞尽脑汁这么多代码,仅仅是实现了这么一点点功能,并且,一些特殊情况(如:新增、移动、更新、删除记录)还没有考虑。 所以,尽可能不采用DBGrid这种控件--->如果实在要用,并且要实现类似功能,那就首选一些三方控件--->如果不想用三方控件,那就尽量把功夫放在DataSet里---->最笨的办法就是象我写的这个测试一样:把精力都放在了摆放控件里了。这样实际上是走了弯路。 直接换成DBGridEH得了,懒得麻烦!!有现成的就用现成的啦 TO:vsice(感情白纸) 用是一方面,更重要的是学习更高层次的东西,如果只是一味的用现成的东西确实方便快捷,但是你 只能永远做一个初级程序员,永远只会拖放几个控件而已。现在很多项目中都需要自己编写特定的控件,如果没有深厚的历练是不行的啊! To caixinke(<<虎讯网>>hoosoon.com) 兄弟说的正确,写代码就要应该这样。我想只有这样我们的技术才能得到提升。 基类Form打包,加入工程中,如何继承包里的Form 请问DELPHI里面的热键在哪里查询 比如 我想把一段代码(很多行) 一起向后走3个空格 请问用什么组合键 请教大侠,关于导数据,在线等,UP有分 小弟要考软件设计师-求建议 用indy传文本格式数据,里面有各种信息,应该以什么形式传呢 要回家过年了,高兴散分! 如何使窗体最大化按钮变灰(新手上路,多多指教) 在ADOQuery中如何判断当前记录是否已经被删除? 时间之差的函数是什么 如何将水晶报表导成EXCEL Delphi如何获取.JPG图象某点的象素信息? 救命,多线程画图
DataCol: Integer; Column: TColumn; State: TGridDrawState);
beginend;
在DBGrid的onDrawColumnCell中编写代码,给出示例,很简单需要你自己去发挥,只是给个思路
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
ck:Tcheckbox;
begin
if DataCol=0 then
begin
ck:=Tcheckbox.Create(self);
ck.Parent:=self;
ck.Width:=14;
ck.Height:=14;
ck.Left:=rect.Left+dbgrid1.Left+2;
ck.Top:=rect.Top+dbgrid1.Top+2;
end;
end;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, DB, Grids, DBGrids, DBTables;type
TForm1 = class(TForm)
Table1: TTable; //这里用一个Table做测试。用其他的DataSet,如Query、ADOQuery等一样
DBGrid1: TDBGrid;
DataSource1: TDataSource;//DataSource1如果换名字,下面的代码要随之更换
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ChkOnClick(Sender: TObject); //注意
end;var
Form1: TForm1;
ChksState : array of boolean; //全程数组,存放每条记录的CheckBox状态implementation{$R *.dfm}procedure TForm1.ChkOnClick(Sender: TObject); //所有CheckBox的Click事件
begin
if TCheckBox(Sender).Checked then
ChksState[DataSource1.DataSet.RecNo-1] := true
else
ChksState[DataSource1.DataSet.RecNo-1] := false;
end;procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
Chk : TCheckBox;
begin
if (TDBGrid(Sender).DataSource.DataSet.Active) and (DataCol = 0) then
begin
Chk := TCheckBox.Create(self);
Chk.Left := Rect.Left + TDBGrid(Sender).Left + 2;
Chk.Top := Rect.Top + TDBGrid(Sender).top + 2;
Chk.Height := Rect.Bottom - Rect.Top - 2;
Chk.Width := Chk.Height;
Chk.Color := clWhite;
if ChksState[TDBGrid(Sender).DataSource.DataSet.RecNo-1] then
Chk.Checked := true else Chk.Checked := false;
Chk.OnClick := ChkOnClick; //注意
Chk.Parent := Self;
Chk.Visible := true;
end;
end;procedure TForm1.Button1Click(Sender: TObject); //打开数据源并构建DBGrid
var
I : integer;
begin
with DBGrid1 do
begin
DataSource := DataSource1;
DataSource.DataSet.Open;
SetLength(ChksState,DataSource.DataSet.RecordCount);
for I := 0 to DataSource.DataSet.FieldCount do
Columns.Add;
Columns[0].Title.Caption := 'Check';
for I := 1 to DataSource.DataSet.FieldCount do
begin
Columns[I].Field := DataSource.DataSet.Fields[I-1];
Columns[I].Title.Caption := 'Field_' + IntToStr(I);
end;
end;
end;procedure TForm1.Button2Click(Sender: TObject); //测试
begin
if ChksState[DataSource1.DataSet.RecNo-1] then
showmessage('当前记录状态= 选中!')
else
showmessage('当前记录 未选中');
end;procedure TForm1.FormCreate(Sender: TObject);
begin
Table1.Close;
DataSource1.DataSet := Table1;
end;end. 在这个测试里,我用了一个Table,其DataBaseName和TableName属性,楼主自己设置。在测试效果按钮Button2里,写出了调用Checked状态的方法:那就是通过DataSet.RecNo对应的ChksState数组元素,来知道该记录是否选中。 这仅是一个演示代码。可以看出,劳心费力绞尽脑汁这么多代码,仅仅是实现了这么一点点功能,并且,一些特殊情况(如:新增、移动、更新、删除记录)还没有考虑。 所以,尽可能不采用DBGrid这种控件--->如果实在要用,并且要实现类似功能,那就首选一些三方控件--->如果不想用三方控件,那就尽量把功夫放在DataSet里---->最笨的办法就是象我写的这个测试一样:把精力都放在了摆放控件里了。这样实际上是走了弯路。
用是一方面,更重要的是学习更高层次的东西,如果只是一味的用现成的东西确实方便快捷,但是你 只能永远做一个初级程序员,永远只会拖放几个控件而已。现在很多项目中都需要自己编写特定的控件,如果没有深厚的历练是不行的啊!
兄弟说的正确,写代码就要应该这样。我想只有这样我们的技术才能得到提升。