即grid.cells[i,0]中只有一个checkbox,checkbox的数量是随着i的数值在变化的
checkbox要和当前行的其它数据关联起来
选中某些checkbox能对打勾的数据进行count操作声明如下:
const  CountMax =50;
var
  checkbox: array of TCheckBox;代码如下:
 for  j:=1 to CountMax do
  begin
     index:=j;
     Grid1.Cells[j,2].Create(checkbox[index]);
  end;该怎么解决? 请高手指教

解决方案 »

  1.   

    对于这个create能不能这么用我都还不太清楚新手哈,见谅
      

  2.   

    给个例子,研究一下吧
    使用ADOConnetction,ADOQuery和DataSource链接.TDBGrid组件的DefaultDrawing属性介绍:该属性是布尔型属性,它用于控制网格中各网格单元的绘制方式.在缺省情况下,该属性的值为True,也就是说Delphi使用网格本身缺省的方法绘制网格中各网格单元,并填充各网格单元中的内容,各网格单元中的数据根据其对应的字段部件的DisplayFormat属性和EditFormat属性进行显示和绘制.如果DefaultDrawing属性被设置成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事件的处理是整个程序的关键.处理嵌入组件的显示的传统方法是:在表单上实际添加组件对象,然后对组件的位置属性与网格中单元格的位置属性进行调整,以达到嵌入的视觉效果.这种方法可行但代码量大,实际运行时控制性很差.利用Win32API的函数DrawFrameControl(),由于此函数可以直接画出CheckBox组件,所以就无须在表单中实际添加组件.此外,在TDBGrid.OnDeawColumnCell事件中,需要设定一个整型数组变量,而这个返回的整数值是与布尔值相一致的,如果字段是逻辑函数,则只是将其布尔值放入数组中,提供给DrawFrameControl()函数中的状态函数进行调用,从而实现CheckBox组件在网格中的嵌入效果.
      

  3.   

    private
        { Private declarations }
        OriginalOptions: TDBGridOptions;
        procedure SaveBoolean;
      public
        { Public declarations }
      end; var
      Form1: TForm1; implementation{$R *.dfm} 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;Z
      

  4.   

    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
      with DBGrid1 do
      begin
        SelectedField.DataSet.Edit;
        SelectedField.AsBoolean:=not SelectedField.AsBoolean;
        SelectedField.DataSet.Post;
      end;
    end;
    //////////////////////////////
    当然,如果怕麻烦的话就直接用CheckBox,然后动态设置Visible属性以及位置就可以了?M
      

  5.   

    直接用CheckBox,然后动态设置Visible属性以及位置就可以了同意楼上的观点。
      

  6.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, ExtCtrls,DateUtils, Grids;type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure FormCreate(Sender: TObject);
        procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
      private
          checkbox: array of TCheckBox;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: Integer;
    begin
      SetLength(CheckBox, StringGrid1.ColCount);
      for i := 0 to  StringGrid1.ColCount -1 do
      begin
        checkbox[i] := TCheckBox.Create(self);
        checkbox[i].Parent := self;
      end;
    end;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
      if(ARow = 2) then
      begin
        checkbox[ACol].Top :=  StringGrid1.Top + Rect.Bottom - Rect.Top + 2;
        checkbox[ACol].Left := Rect.Left + StringGrid1.Left + 2;
        checkbox[ACol].Width := Rect.Right - Rect.Left;
        checkbox[ACol].Height := Rect.Bottom - Rect.Top;
      end;
    end;end.
      

  7.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, ExtCtrls,DateUtils, Grids;type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure FormCreate(Sender: TObject);
        procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
      private
          checkbox: array of TCheckBox;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: Integer;
    begin
      SetLength(CheckBox, StringGrid1.ColCount);
      for i := 0 to  StringGrid1.ColCount -1 do
      begin
        checkbox[i] := TCheckBox.Create(self);
        checkbox[i].Parent := self;
      end;
    end;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
      if(ARow = 2) then
      begin
        checkbox[ACol].Top :=  StringGrid1.Top + Rect.Bottom - Rect.Top + 2;
        checkbox[ACol].Left := Rect.Left + StringGrid1.Left + 2;
        checkbox[ACol].Width := Rect.Right - Rect.Left;
        checkbox[ACol].Height := Rect.Bottom - Rect.Top;
      end;
    end;end.
      

  8.   

    对于stringgrid的那种做法,我试了一下。确实能显示多个checkbox但是我想要的是一列的效果,不是一行
    对了,有没有方法可以将checkbox中的那个正方形的框放在cell的中央呢?
      

  9.   

    将if(ARow = 2) then
    改为 if(ACol= n) then
    然后调整
        checkbox[ACol].Top 
        checkbox[ACol].Left 
        checkbox[ACol].Width 
        checkbox[ACol].Height 
    的位置
    就可以实现
      

  10.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids,StdCtrls;
    const
      CountMax = 50;
    type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure FormCreate(Sender: TObject);
        procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
      private
         checkbox: array of TCheckBox;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    var
      i: Integer;
    begin
      SetLength(CheckBox, StringGrid1.RowCount);
      for i := 0 to  StringGrid1.RowCount -1 do
      begin
        checkbox[i] := TCheckBox.Create(self);
        checkbox[i].Parent := self;
      end;
    end;procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    var
      j: integer;
    begin
      for j:=1 to CountMax do
      begin
        ACol := j;
        if(ACol = j) then
        begin
          checkbox[ACol].Color:=clWhite;
          checkbox[ACol].Top :=  StringGrid1.Top + Rect.Bottom - Rect.Top + 2;
          checkbox[ACol].Left := Rect.Left + StringGrid1.Left + 2;
          checkbox[ACol].Width := Rect.Right - Rect.Left;
          checkbox[ACol].Height := Rect.Bottom - Rect.Top;
        end;
      end;
    end;
    end.改成这样还是出错。不知道原因了。
      

  11.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Grids;type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      check:Array of Tcheckbox;
    implementation{$R *.dfm}procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
       if (ACol=2) then
       begin
        // if ARow<>0 then
        // begin
           //check[ARow].Left:=Rect.Left+Stringgrid1.Left+27;
           //check[ARow].Top:=Rect.top+Stringgrid1.top+8;       check[ARow].Left:=Stringgrid1.Left+152;
           check[ARow].Top:=Rect.top+Stringgrid1.top+8;
           check[ARow].Caption:='';
           check[ARow].Color:=clwindow;
           check[ARow].Width:= Rect.right-Stringgrid1.left-38;
           check[ARow].Height:=  12;
         //end;
       end;
      
    end;procedure TForm1.FormCreate(Sender: TObject);var
     i:integer;
    begin
      setlength(check,stringgrid1.RowCount-1);
      for i:=0 to stringgrid1.RowCount-1 do
      begin
        check[i]:=Tcheckbox.Create(self);
        check[i].Parent:=self;
        check[i].Show;
      end;
    end;end.这样会在form的左上角加了一个checkbox。也不知道原因
      

  12.   

    知道原因了,checkbox是从1开始计数的。
    应该formcreate时改成
    for i:=1 to stringgrid1.RowCount-1 do
    即可终于解决了,多谢大家帮忙。