自:http://rabbitfox.blog.sohu.com/33264033.html
http://community.csdn.net/Expert/topic/5342/5342920.xml?temp=.9525568
問:如何使dbgrid增加一列類似checkbox的控件,可以用鼠標來選擇該行是否被選中,可以多選
最好的思路還是要在數據表里增加一個布爾字段,然后用DBCheckBox與它關聯,而不是CheckBox。(至於在DBGrid里嵌入DBCheckBox的方法,可以參考:http://topic.csdn.net/t/20021118/16/1186480.html)
如果就是不希望在數據表里增加一個布爾字段,就是想用CheckBox,下面是我的測試代碼供參考:
unit Unit1;
interface
uses
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里---->最笨的辦法就是象我寫的這個測試一樣:把精力都放在了擺放控件里了。這樣實際上是走了彎路。
http://www.cnblogs.com/hssbsw/archive/2012/06/15/2551438.html
