类似MSSQL创建表差不多的功能,就是允许输入一行,一旦输入某一行后,自动添加下一个空白行。同时支持选中行删除。 这是困扰我两天的难题,最后还是到论坛发帖求助,求一解决方案 unit gridtest; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls; type TForm1 = class(TForm) StringGrid1: TStringGrid; procedure FormCreate(Sender: TObject); procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure StringGrid1Click(Sender: TObject); procedure StringGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure StringGrid1DblClick(Sender: TObject); private { Private declarations } public { Public declarations } fcheck,fnocheck:tbitmap; procedure init; procedure addgrid; procedure DeleteRow(ARow: Longint); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.init; var i:SmallInt; bmp:TBitmap; begin FCheck:= TBitmap.Create; FNoCheck:= TBitmap.Create; bmp:= TBitmap.create; try bmp.handle := LoadBitmap( 0, PChar(OBM_CHECKBOXES )); With FNoCheck Do Begin width := bmp.width div 4; height := bmp.height div 3; canvas.copyrect( canvas.cliprect, bmp.canvas, canvas.cliprect ); End; With FCheck Do Begin width := bmp.width div 4; height := bmp.height div 3; canvas.copyrect( canvas.cliprect, bmp.canvas, rect( width, 0, 2*width, height )); End; finally bmp.free; end; StringGrid1.Cells[1,0]:='列名'; StringGrid1.Cells[2,0]:='数据类型'; StringGrid1.Cells[3,0]:='充许空'; end; procedure TForm1.addgrid; var i: Integer; CurrentRow:integer; begin //先增加一行 StringGrid1.RowCount := StringGrid1.RowCount + 1; StringGrid1.Rows[StringGrid1.RowCount - 1].Clear; //移形换位,把最后一行跟你指定的行换位置! CurrentRow := StringGrid1.Row+1; for i := StringGrid1.RowCount - 1 downto CurrentRow + 1 do begin StringGrid1.Rows[i].Assign(StringGrid1.Rows[i - 1]); end; StringGrid1.Rows[CurrentRow].Clear; StringGrid1.Row := CurrentRow; SendMessage(StringGrid1.Handle, EM_SCROLLCARET, 0, 0);//多送你一个方法:滚动到插入行的位置 end; procedure TForm1.DeleteRow(ARow:integer); var i,mrow:integer; begin if arow<2 then //保留一行 exit; with stringgrid1 do begin mrow:=RowCount; for i:=arow to mrow-2 do Rows[i].Assign(Rows[i+1]); rowcount:=rowcount-1; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Init; end; procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); begin if (acol=3) and (arow>=1) then begin if not (gdFixed in State) then with TStringGrid(Sender).Canvas do begin brush.Color:=clWindow; FillRect(Rect); if StringGrid1.Cells[ACol,ARow]='yes' then Draw( (rect.right + rect.left - FCheck.width) div 2, (rect.bottom + rect.top - FCheck.height) div 2, FCheck ) else Draw( (rect.right + rect.left - FCheck.width) div 2, (rect.bottom + rect.top - FCheck.height) div 2, FNoCheck ); end; end; end; procedure TForm1.StringGrid1Click(Sender: TObject); begin if (StringGrid1.col=3) and (StringGrid1.row>=1) then begin StringGrid1.Options:=StringGrid1.Options-[goEditing] ; if StringGrid1.Cells[StringGrid1.col,StringGrid1.row]='yes' then StringGrid1.Cells[StringGrid1.col,StringGrid1.row]:='no' else StringGrid1.Cells[StringGrid1.col,StringGrid1.row]:='yes'; end else StringGrid1.Options:=StringGrid1.Options+[goEditing] ; end; procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (key=vk_down) and ( StringGrid1.Row=StringGrid1.RowCount-1) then addgrid; end; procedure TForm1.StringGrid1DblClick(Sender: TObject); begin DeleteRow( StringGrid1.Row); end; end.