zoukankan      html  css  js  c++  java
  • Delphi StringGrid控件的用法

    Delphi StringGrid控件

    组件名称:StringGrid   
        
    ●固定行及固定列: 
    StringGrid.FixedCols:=固定行之数; 
    StringGrid.FixedRows:=固定列之数; 
    StringGrid. FixedColor:=固定行列之颜色; 
    StringGrid.Color:=资料区之颜色; 

    ●资料行列之宽高度: 
    StringGrid.DefaultColWidth:=内定全部之宽度; 
    StringGrid.DefaultRowHeight:=内定全部之高度; 
    StringGrid.ColWidths[Index:Longint]:=某一行整行之宽度; 
    StringGrid.RowHeights[Index:Longint]:=某一列整列之高度; 

    ●数据区(CELL)指定: 
    将某一行列停在画面之资料区最左上角: 
    StringGrid.LeftCol:=某一行号; 
    StringGrid.TopRow:=某一列号; 
    焦点移至某一格(CELL)内: 
    StringGrid.Row:=?; 
    StringGrid.Col:=?; 
    设定数据行列数:(包含固定行、列亦算在内) 
    StringGrid.RowCount:=?; 
    StringGrid.ColCount:=?; 
    写一字符串至某一格(CELL)内: 
    StringGrid.Cells[Col值 , Row值]:=字符串; 
    判断鼠标指针目前在哪一格(CELL)范围内: 
    在StringGrid之Mouse事件中(UP,DOWN或MOVE)下: 
    VAR C , R : Longint; 
    Begin 
    StringGrid.MouseToCell(X,Y,C,R); {X,Y由MOUSE事件传入} 
    {取回 C , R 即为目前之Col , Row值 } 
    ...... 

    ●StringGrid之Options属性: 
    若要于程序执行中开启或关闭Options某一功能如 ‘goTABS’ 
    开: StringGrid.Options:= StringGrid.Options + [goTABS]; 
    关: StringGrid.Options:= StringGrid.Options - [goTABS]; 


    goFixedHorzLine 固定列间之水平线 
    goFixedVertLine 固定行间之垂直线 
    goHorzLine 资料格间水平线 
    goVertLine 资料格间垂直线 
    goRangeSelect 鼠标可多重选择 
    goDrawFocusSelected 多重选择时,第一数据项反白 
    goRowSizing 鼠标可改变列高 
    goColSizing 鼠标可改变行宽 
    goRowMoving 鼠标可搬数据列 
    goColMoving 鼠标可搬数据行 
    goEditing 可编辑(与鼠标可多重选择互斥) 
    goAlwaysShowEditor 须有goEditing,不用按F4或ENTER即有等待输入光标 
    goTabs 允许TAB及Shift-TAB移动光标 
    goRowSelect 用鼠标点一下可选取整列(亦与鼠标可多重选择互斥) 
    goThumbTracking 滚动条动时GRID跟着动,否则滚动条动完放开,GRID才动





    StringGrid使用全书
    StringGrid行列的增加和删除
    如何编写使StringGrid中的一列具有Check功能,和CheckBox效果一样
    StringGrid组件Cells内容分行显示在Tstringgrid.ondrawcell事件中
    在StringGrid怎样制作只读的列在 OnSelectCell事件处理程序中
    stringgrid从文本读入的问题
    StringGrid组件Cells内容对齐
    StringGird的行列背景色设置
    怎么改变StringGrid控件某一列的背景和某一列的只读属性
    StringGrid控件标题栏的对齐
    怎么改变StringGrid控件某一列的背景和某一列的只读属性
    StringGrid控件标题栏的对齐
    在stringGrid中使用回车键模拟TAB键切换单元格的功能实现
    stringgrid如何清空
    让记录在StringGrid中分页显示在
    打印StringGrid
    如何实现在stringgrid中删除鼠标点中的那一行,下一行再顶上的效果
    让stringgrid点列头进行排序
    正确地设置StringGrid列宽而不截断任何一个文字方法
    实现StringGrid的删除,插入,排序行操作
    TstringGrid 的行列合并研究
    StringGrid行列的增加和删除
    type
     TExCell = class(TStringGrid)
    public
     procedure DeleteRow(ARow: Longint);
     procedure DeleteColumn(ACol: Longint);
     procedure InsertRow(ARow: LongInt);
     procedure InsertColumn(ACol: LongInt);
    end;
    procedure TExCell.InsertColumn(ACol: Integer);
    begin
     ColCount :=ColCount +1;
     MoveColumn(ColCount-1, ACol);
    end;
    procedure TExCell.InsertRow(ARow: Integer);
    begin
     RowCount :=RowCount +1;
     MoveRow(RowCount-1, ARow);
    end;
    procedure TExCell.DeleteColumn(ACol: Longint);
    begin
     MoveColumn(ACol, ColCount -1);
     ColCount := ColCount - 1;
    end;
    procedure TExCell.DeleteRow(ARow: Longint);
    begin
     MoveRow(ARow, RowCount - 1);
     RowCount := RowCount - 1;
    end;
     如何编写使StringGrid中的一列具有Check功能,和CheckBox效果一样
     unit Unit1;
    interface
    uses
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids;
    type
     TForm1 = class(TForm)
     grid: TStringGrid;
     procedure FormCreate(Sender: TObject);
     procedure gridDrawCell(Sender: TObject; ACol, ARow: Integer;
     Rect: TRect; State: TGridDrawState);
     procedure gridClick(Sender: TObject);
     private
    { Private declarations }
     public
    { Public declarations }
    end;
    var
     Form1: TForm1;
     fcheck,fnocheck:tbitmap;
    implementation
    {$R *.DFM}
    procedure TForm1.FormCreate(Sender: TObject);
    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;
    end;
    procedure TForm1.gridDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
    begin
     if not (gdFixed in State) then
       with TStringGrid(Sender).Canvas do
     begin
       brush.Color:=clWindow;
       FillRect(Rect);
       if Grid.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;
    procedure TForm1.gridClick(Sender: TObject);
    begin
     if grid.Cells[grid.col,grid.row]='yes' then
       grid.Cells[grid.col,grid.row]:='no'
     else
       grid.Cells[grid.col,grid.row]:='yes';
    end;
    end.


    StringGrid组件Cells内容分行显示在Tstringgrid.ondrawcell事件中:
     DrawText(StringGrid1.Canvas.Handle,pchar(StringGrid1.Cells[Acol,Arow]),Length(StringGrid1.Cells[Acol,Arow]),Rect,DT_WORDBREAK or DT_LEFT);
    可以实现文字换行!
    在StringGrid怎样制作只读的列在 OnSelectCell事件处理程序中,
    加入: (所有的列均设成可修改的)
     if Col mod 2 = 0 then
       grd.Options := grd.Options + [goEditing]
     else
       grd.Options := grd.Options - [goEditing];


    stringgrid从文本读入的问题(Save/Load a TStringGrid to/from a file?)
    // Save a TStringGrid to a file
    procedure SaveStringGrid(StringGrid: TStringGrid; const FileName: TFileName);
    var
     f: TextFile;
     i, k: Integer;
    begin
     AssignFile(f, FileName);
     Rewrite(f);
     with StringGrid do
     begin
       // Write number of Columns/Rows
       Writeln(f, ColCount);
       Writeln(f, RowCount);
       // loop through cells
       for i := 0 to ColCount - 1 do
         for k := 0 to RowCount - 1 do
           Writeln(F, Cells[i, k]);
     end;
     CloseFile(F);
    end;
    // Load a TStringGrid from a file
    procedure LoadStringGrid(StringGrid: TStringGrid; const FileName: TFileName);
    var
     f: TextFile;
     iTmp, i, k: Integer;
     strTemp: String;
    begin
     AssignFile(f, FileName);
     Reset(f);
     with StringGrid do
     begin
       // Get number of columns
       Readln(f, iTmp);
       ColCount := iTmp;
       // Get number of rows
       Readln(f, iTmp);
       RowCount := iTmp;
       // loop through cells & fill in values
       for i := 0 to ColCount - 1 do
         for k := 0 to RowCount - 1 do
         begin
           Readln(f, strTemp);
           Cells[i, k] := strTemp;
         end;
       end;
     CloseFile(f);
    end;
    // Save StringGrid1 to 'c:.txt':
    procedure TForm1.Button1Click(Sender: TObject);
    begin
     SaveStringGrid(StringGrid1, 'c:.txt');
    end;
    // Load StringGrid1 from 'c:.txt':
    procedure TForm1.Button2Click(Sender: TObject);
    begin
     LoadStringGrid(StringGrid1, 'c:.txt');
    end;
    *******************************************
    打开一个已有的文本文件,并将内容放到stringgrid中,文本行与stringgrid行一致;
    在文本中遇到空格则放入下一cells.
    搞定!注意,我只写了一个空格间隔的,你自己修改一下splitstring可以用多个空格分隔!
    procedure TForm1.Button1Click(Sender: TObject);
    var
     aa,bb:tstringlist;
     i:integer;
    begin
     aa:=tstringlist.Create;
     bb:=tstringlist.Create;
     aa.LoadFromFile('c:.txt');
     for i:=0 to aa.Count-1 do
     begin
       bb:=SplitString(aa.Strings[i],' ');
       stringgrid1.Rows[i]:=bb;
     end;
     aa.Free;
     bb.Free;
    end;
    其中splitstring为:
    function SplitString(const source,ch:string):tstringlist;
    var
     temp:string;
     i:integer;
    begin
     result:=tstringlist.Create;
     temp:=source;
     i:=pos(ch,source);
     while i<>0 do
     begin
       result.Add(copy(temp,0,i-1));
       delete(temp,1,i);
       i:=pos(ch,temp);
     end;
     result.Add(temp);
    end;


    StringGrid组件Cells内容对齐
    在StringGrid的DrawCell事件中添加类似的代码就可以了:
    VAR
     vCol, vRow : LongInt;
    begin
     vCol := ACol; vRow := ARow;
     WITH Sender AS TStringGrid, Canvas DO
       IF vCol = 2 THEN BEGIN ///对于第2列设置为右对齐
         SetTextAlign(Handle, TA_RIGHT);
         FillRect(Rect);
         TextRect(Rect, Rect.RIGHT-2, Rect.Top+2, Cells[vCol, vRow]);
       END;
    end;
    当我将StringGird的options属性中包含goRowSelect项时每当我选中StringGrid中一行, 则选中行用深蓝色显示,我想将深蓝色改为其他颜色应怎样该?当我将StringGird的options属性中包含goRowSelect项时每当我选中StringGrid中一行, 则选中行用深蓝色显示,我想将深蓝色改为其他颜色应怎样该?
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
    Rect: TRect; State: TGridDrawState);
    begin
     With StringGrid1 do
     begin
       If  (ARow= Krow) and not (acol = 0) then
       begin
          Canvas.Brush.Color :=clYellow;// ClBlue;
          Canvas.FillRect(Rect);
          Canvas.font.color:=ClBlack;
          Canvas.TextOut(rect.left , rect.top, cells[acol, arow]);
       end;
     end;
    end;
    procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
     ARow: Integer; var CanSelect: Boolean);
    begin
     krow := Arow;  //*
     kcol := Acol;
    end;
    注意:必须把变量KROW的值初始为1或其他不为0的值,否则如果锁定第一行的话,第一行的颜色将被自设颜色取代,而锁定行不会被重画。


     怎么改变StringGrid控件某一列的背景和某一列的只读属性,StringGrid控件标题栏的对齐.怎么改变StringGrid控件某一列的背景和某一列的只读属性,StringGrid控件标题栏的对齐.
    请参考以下代码:
     在OnDrawCell事件中处理背景色。程序如下:
    //将第二列背景变为红色。
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
     Rect: TRect; State: TGridDrawState);
    begin
     if not((acol=1) and (arow>=stringgrid1.fixedrows)) then exit;
     with stringgrid1 do
     begin
       canvas.Brush.color:=clRed;
       canvas.FillRect(Rect);
       canvas.TextOut(rect.left+2,rect.top+2,cells[acol,arow])
     end;
    end;
    //加入如下代码,那么StringGrid的第四列就只读了.其他列非只读
    procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
    begin
     with StringGrid1 do begin
       if ACol = 4 then
         Options := Options - [goEditing]
       else Options := Options + [goEditing];
    end;
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
    var
     dx,dy:byte;
    begin
     if (acol = 4) and not (arow = 0) then
       with stringgrid1 do
       begin
         canvas.Brush.color := clYellow;
         canvas.FillRect(Rect);
         canvas.font.color := clblue;
         dx:=2;//调整此值,控制字在网格中显示的水平位置
         dy:=2;//调整此值,控制字在网格中显示的垂直位置
         canvas.TextOut(rect.left+dx , rect.top+dy , cells[acol, arow]);
       end;
    //控制标题栏的对齐
     if (arow = 0) then
       with stringgrid1 do
       begin
         canvas.Brush.color := clbtnface;
         canvas.FillRect(Rect);
         dx := 12; //调整此值,控制字在网格中显示的水平位置
         dy := 5; //调整此值,控制字在网格中显示的垂直位置
         canvas.TextOut(rect.left + dx, rect.top + dy, cells[acol, arow]);
       end;
    end;


     2003-11-17 16:37:15    在stringGrid中使用回车键模拟TAB键切换单元格的功能实现......
    procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
     label
     nexttab;
    begin
     if key=#13 then
     begin
       key:=#0;
       nexttab:
       if (stringgrid1.Col<stringgrid1.ColCount-1) then
         begin
           stringgrid1.Col:=stringgrid1.Col+1;
         end
       else
       begin
         if stringgrid1.Row>=stringgrid1.RowCount-1 then
           stringgrid1.RowCount:=stringgrid1.rowCount+1;
         stringgrid1.Row:=stringgrid1.Row+1;
         stringgrid1.Col:=0;
         goto nexttab;
       end;
     end;
    end;
    .........


    stringgrid如何清空
    with StringGrid1 do for I := 0 to ColCount - 1 do Cols[I].Clear;
    选中某单元格,然后在该单元格中修改-> 选中某单元格,然后在该单元格中修改
    设置属性:
       StringGrid1.Options:=StringGrid1.Options+[goEditing];
    让记录在StringGrid中分页显示
    在Uses中加入: ADOInt
    //首先设定PageSize,取出PageCount
    procedure TForm1.Button1Click(Sender: TObject);
    begin
     ADoquery1.Recordset.PageSize :=spinedit1.Value;
     Edit1.Text := IntToStr(ADoquery1.Recordset.PageCount);
     ShowData(spinedit2.Value);
    end;
    //然后将AbsolutePage的数据乾坤大挪移到StringGrid1中
    procedure TForm1.ShowData(page:integer);
    var
     iRow, iCol, iCount : Integer;
     rs : ADOInt.Recordset;
    begin
     ADoquery1.Recordset.AbsolutePage:=Page;
     Currpage:=page;
     iRow := 0;
     iCol := 1;
     stringgrid1.Cells[iCol, iRow] := 'FixedCol1';
     Inc(iCol);
     stringgrid1.Cells[iCol, iRow] := 'FixedCol2';
     Inc(iRow);
     Dec(iCol);
     rs := adoquery1.Recordset;
     for iCount := 1 to SpinEdit1.Value do
     begin
       stringgrid1.Cells[iCol, iRow] := rs.Fields.Get_Item('FieldName1').Value;
       Inc(iCol);
       stringgrid1.Cells[iCol, iRow] := rs.Fields.Get_Item('FieldName1').Value;
       Inc(iRow);
       Dec(iCol);
       rs.MoveNext;
     end;
    //上一页
    procedure TForm1.Button2Click(Sender: TObject);
    begin
     If (CurrPage)<>1 then
       ShowData(CurrPage-1);
    end;
    //下一页
    procedure TForm1.Button3Click(Sender: TObject);
    begin
     If CurrPage<>ADoquery1.Recordset.PageCount then
       ShowData(CurrPage+1);
    end;
    打印StringGrid的程序源码
    这段代码没有看懂,但是可能有的朋友需要,所以共享一下子 :)
    procedure TForm1.SpeedButton11Click(Sender: TObject);
    Var
     Index_R ,ALeft: Integer;
     Index : Integer;
    begin
     StringGrid_File('D:AAA.TXT');
     if Not LinkTextFile then
     begin
       ShowMessage('失败');
       Exit;
     end;
     //
     QuickRep1.DataSet := ADOTable1;
     Index_R := ReSize(StringGrid1.Width);
     ALeft := 13;
     Create_Title(TitleBand1,ALeft,24,HeaderControl1.Sections.Items[0].Width,20,
        HeaderControl1.Sections[0].Text,taLeftJustify);
     with Create_QRDBText(DetailBand1,ALeft,8,StringGrid1.ColWidths[0],20,
            StringGrid1.Font,taLeftJustify) do
     begin
       DataSet := ADOTable1;
       DataField := ADOTable1.Fields[0].DisplayName;
     end;
     ALeft := ALeft + StringGrid1.ColWidths[0] * Index_R + Index_R;
     For Index := 1 to ADOTable1.FieldCount - 1 do
     begin
       Create_VLine(TitleBand1,ALeft - 13,16,1,40);
       Create_Title(TitleBand1,ALeft,24,HeaderControl1.Sections.Items[Index].Width,20,
         HeaderControl1.Sections[Index].Text,taLeftJustify);
       Create_VLine(DetailBand1,ALeft - 13,-1,1,31);
       with Create_QRDBText(DetailBand1,ALeft ,8,StringGrid1.ColWidths[Index] * Index_R,20,
            StringGrid1.Font,taLeftJustify) do
       begin
         DataSet := ADOTable1;
         DataField := ADOTable1.Fields[Index].DisplayName;
       end;
       ALeft := ALeft + StringGrid1.ColWidths[Index] *  Index_R + Index_R;
     end;
     QuickRep1.Preview;
    end;
    function TForm1.ReSize(AGridWidth: Integer): Integer;
    begin
     Result := Trunc(718 / AGridWidth);
    end;
    function TForm1.StringGrid_File(AFileName: String): Boolean;
    var
     StrValue : String;
     Index : Integer;
     ACol , ARow : Integer;
     AFileValue : System.TextFile;
    begin
     StrValue := '';
     Try
       AssignFile(AFileValue , AFileName);
       ReWrite(AFileValue);
       StrValue := HeaderControl1.Sections[0].Text;
       For Index := 1 to HeaderControl1.Sections.Count - 1 do
         StrValue := StrValue + ',' + HeaderControl1.Sections[Index].Text;
       Writeln(AFileValue,StrValue);
       StrValue := '';
       For  ARow := 0 To StringGrid1.RowCount - 1 do
       begin
         StrValue := '';
         StrValue := StringGrid1.Cells[0,ARow];
         For ACol := 1 To StringGrid1.ColCount - 1 do
         begin
           StrValue := StrValue + ', ' + StringGrid1.Cells[ACol,ARow];
         end;
         Writeln(AFileValue,StrValue);
       end;
     Finally
       CloseFile(AFileValue);
     end;
    end;
    function TForm1.LinkTextfile: Boolean;
    begin
     Result := False;
     with ADOTable1 do
     begin
       {ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;' +
                           'Data Source= D:;Extended Properties=Text;' +
                           'Persist Security Info=False';
       TableName := 'AAA#TXT';
       Open;       }
       if Active then
         Result := True;
     end;
    end;
    function TForm1.Create_QRDBText(Sender: TWinControl; ALeft, ATop, AWidth,
     AHight: Integer; AFont: TFont; AAlignMent: TAlignment): TQRDBText;
    var
     AQRDBText : TQRDBText;
    begin
     AQRDBText := TQRDBText.Create(Nil);
     with AQRDBText do
     begin
       Parent := Sender;
       Left := ALeft;
       Top := ATop;
       Width := AWidth;
       Height := AHight;
       AlignMent := AAlignMent;
       Font.Assign(AFont);
     end;
     Result := AQRDBText;
    end;
    function TForm1.Create_VLine(Sender: TWinControl; ALeft, ATop, AWidth,
     AHight: Integer): TQRShape;
    var
     AQRShapeV : TQRShape;
    begin
     AQRShapeV := TQRShape.Create(Nil);
     with AQRShapeV do
     begin
       Parent := Sender;
       Left := ALeft;
       Top := ATop;
       Width := AWidth;
       Height := AHight;
     end;
     Result := AQRShapeV;
    end;
    procedure TForm1.Create_Title(Sender: TWinControl; ALeft, ATop, AWidth,
     AHight: Integer; ACaption: String; AAlignMent: TAlignment);
    var
     AQRLabel : TQRLabel;
    begin
     AQRLabel := TQRLabel.Create(Nil);
     with AQRLabel do
     begin
       Parent := Sender;
       Left := ALeft;
       Top := ATop;
       Width := AWidth;
       AlignMent := AAlignMent;
       Caption := ACaption;
     end;
    end;
    -----------------------------


    如何实现在stringgrid中删除鼠标点中的那一行,下一行再顶上的效果?
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Sel : TGridRect;
    begin
    Sel := StringGrid1.Selection;
    DeleteRow(Sel.Top);
    end;
    // delete row
    procedure TForm1.DeleteRow(Row: Integer);
    var
    i : integer;
    begin
    if (Row < StringGrid1.RowCount) and (Row > Stringgrid1.FixedRows-1) then
      if Row < StringGrid1.RowCount - 1 then
      begin
        for i := Row to StringGrid1.RowCount-1 do
          StringGrid1.Rows[i] := StringGrid1.Rows[i+1];
        StringGrid1.RowCount := StringGrid1.RowCount - 1;
      end
      else stringGrid1.Rows[Row].Clear;
    end;
    让stringgrid点列头进行排序
    procedure GridQuickSort(Grid: TStringGrid; ACol: Integer; Order: Boolean ; NumOrStr: Boolean);
    (******************************************************************************)
    (*  函数名称:GridQuickSort                                                   *)
    (*  函数功能:给 StringGrid 的 ACol 列快速法排序    _/_/     _/_/  _/_/_/_/_/ *)
    (*  参数说明:                                          _/   _/        _/      *)
    (*            Order: True 从小到大                       _/          _/       *)
    (*                 : False 从大到小                     _/          _/        *)
    (*        NumOrStr : true 值的类型是Integer          _/_/        _/_/         *)
    (*                 : False 值的类型是String                                   *)
    (*  函数说明:对于日期,时间等类型数据均可按字符方式排序,                    *)
    (*                                                                            *)
    (*                                                                            *)
    (*                                             Author: YuJie  2001-05-27      *)
    (*                                             Email : yujie_bj@china.com     *)
    (******************************************************************************)
    procedure MoveStringGridData(Grid: TStringGrid; Sou,Des :Integer );
    var
      TmpStrList: TStringList ;
      K : Integer ;
    begin
      try
        TmpStrList :=TStringList.Create() ;
        TmpStrList.Clear ;
        for K := Grid.FixedCols to Grid.ColCount -1 do
          TmpStrList.Add(Grid.Cells[K,Sou]) ;
        Grid.Rows [Sou] := Grid.Rows [Des] ;
        for K := Grid.FixedCols to Grid.ColCount -1 do
          Grid.Cells [K,Des]:= TmpStrList.Strings[K] ;
      finally
        TmpStrList.Free ;
      end;
    end;
    procedure QuickSort(Grid: TStringGrid; iLo, iHi: Integer);
    var
      Lo, Hi : Integer;
      Mid: String ;
    begin
      Lo := iLo ;
      Hi := iHi ;
      Mid := Grid.Cells[ACol,(Lo + Hi) div 2];
      repeat
        if Order and not NumOrStr then //按正序、字符排
        begin
          while Grid.Cells[ACol,Lo] < Mid do Inc(Lo);
          while Grid.Cells[ACol,Hi] > Mid do Dec(Hi);
        end ;
        if not Order and not NumOrStr then //按反序、字符排
        begin
          while Grid.Cells[ACol,Lo] > Mid do Inc(Lo);
          while Grid.Cells[ACol,Hi] < Mid do Dec(Hi);
        end;
        if NumOrStr then
        begin
          if Grid.Cells[ACol,Lo] = '' then Grid.Cells[ACol,Lo] := '0' ;
          if Grid.Cells[ACol,Hi] = '' then Grid.Cells[ACol,Hi] := '0' ;
          if Mid = '' then Mid := '0' ;
          if Order then
          begin //按正序、数字排
            while StrToFloat(Grid.Cells[ACol,Lo]) < StrToFloat(Mid) do Inc(Lo);
            while StrToFloat(Grid.Cells[ACol,Hi]) > StrToFloat(Mid) do Dec(Hi);
          end else
          begin //按反序、数字排
            while StrToFloat(Grid.Cells[ACol,Lo]) > StrToFloat(Mid) do Inc(Lo);
            while StrToFloat(Grid.Cells[ACol,Hi]) < StrToFloat(Mid) do Dec(Hi);
          end;
        end ;
        if Lo <= Hi then
        begin
          MoveStringGridData(Grid, Lo, Hi) ;
          Inc(Lo);
          Dec(Hi);
        end;
      until Lo > Hi;
      if Hi > iLo then QuickSort(Grid, iLo, Hi);
      if Lo < iHi then QuickSort(Grid, Lo, iHi);
    end;
    begin
    try
      QuickSort(Grid, Grid.FixedRows, Grid.RowCount - 1 ) ;
    except
    on E: Exception do
      Application.MessageBox(Pchar('系统在排序数据的时候遇到异常:'#13+E.message+#13'请重试,如果该问题依然存在请与程序供应商联系!'),'系统错误',MB_OK+MB_ICONERROR) ;
    end;
    end;
    procedure StringGridTitleDown(Sender: TObject;
    Button: TMouseButton;  X, Y: Integer);
    (******************************************************************************)
    (*  函数名称:StringGridTitleDown                                             *)
    (*  函数功能:取鼠标点StringGrid 的列                _/_/     _/_/  _/_/_/_/_/ *)
    (*  参数说明:                                          _/   _/        _/      *)
    (*            Sender                                     _/          _/       *)
    (*                                                      _/          _/        *)
    (*                                                   _/_/        _/_/         *)
    (*                                                                            *)
    (*                                                                            *)
    (*                                             Author: YuJie  2001-05-27      *)
    (*                                             Email : yujie_bj@china.com     *)
    (******************************************************************************)
    var
    I: Integer ;
    begin
    if (Y > 0 ) and (y < TStringGrid(Sender).DefaultRowHeight * TStringGrid(Sender).FixedRows ) then
    begin
      if  Button = mbLeft then
      begin
        I := X div  TStringGrid(Sender).DefaultColWidth ;
        //这个i 就是要排序得行了
        // 下面调用上面的排序函数就可以了,
        GridQuickSort(TStringGrid(Sender), I, False, True) ;
      end;
    end;
    end;
       用上面的两个函数就能解决你的问题了。在TStringGrid 的MouseDown事件中调用StringGridTitleDown 函数就可以。你可能要修改一下StringGridTitleDown函数来修改排序得方式及其字符类型。
       提醒你一下对于日期、时间、布尔等类型数据均可按字符方式排序。
    例如:
    procedure TForm_Main.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
    StringGridTitleDown(Sender,Button,X,Y);
    end;
    正确地设置StringGrid列宽而不截断任何一个文字方法
    是在对StringGrid填充完文本串后调用SetOptimalGridCellWidth过程。
     -----------程序片断-------------------------------------------------
     (*
     $Header$
     Module Name : GeneralBSGrids.pas
     Main Program : Several.
     Description : StringGrid support functions.
     03/21/2000 enhanced by William Sorensen
     *)
     unit BSGrids;
     interface
     uses
       Grids;
     type
       TExcludeColumns = set of 0..255;
       procedure SetOptimalGridCellWidth(sg: TStringGrid;
       ExcludeColumns: TExcludeColumns);
       // Sets column widths of a StringGrid to avoid truncation of text.
       // Fill grid with desired text strings first.
       // If a column contains no text, DefaultColWidth will be used.
       // Pass [] for ExcludeColumns to process all columns, including Fixed.
       // Columns whose numbers (0-based) are specified in ExcludeColumns will not
       // have their widths adjusted.
     implementation
     uses
       Math; // we need the Max function
       procedure SetOptimalGridCellWidth(sg: TStringGrid;
       ExcludeColumns: TExcludeColumns);
     var
       i : Integer;
       j : Integer;
       max_width : Integer;
     begin
       with sg do
       begin
         // If the grid's Paint method hasn't been called yet,
         // the grid's canvas won't use the right font for TextWidth.
         // (TCustomGrid.Paint normally sets this, under DrawCells.)
         Canvas.Font.Assign(Font);
         for i := 0 to (ColCount - 1) do
         begin
           if i in ExcludeColumns then
             Continue;
           max_width := 0;
           // Search for the maximal Text width of the current column.
           for j := 0 to (RowCount - 1) do
             max_width := Math.Max(max_width,Canvas.TextWidth(Cells[i,j]));
           // The hardcode of 4 is based on twice the offset from the left
           // margin in TStringGrid.DrawCell. GridLineWidth is not relevant.
           if max_width > 0 then
             ColWidths[i] := max_width + 4
           else
             ColWidths[i] := DefaultColWidth;
         end; { for }
       end;
     end;
     end.
    实现StringGrid的删除,插入,排序行操作(基本操作啦)
    //实现删除操作
     Procedure GridRemoveColumn(StrGrid: TStringGrid; DelColumn: Integer);
     Var Column: Integer;
     begin
       If DelColumn <= StrGrid.ColCount then
       Begin
         For Column := DelColumn To StrGrid.ColCount-1 do
           StrGrid.Cols[Column-1].Assign(StrGrid.Cols[Column]);
         StrGrid.ColCount := StrGrid.ColCount-1;
       End;
     end;
    //实现添加插入操作
     Procedure GridAddColumn(StrGrid: TStringGrid; NewColumn: Integer);
     Var Column: Integer;
     begin
       StrGrid.ColCount := StrGrid.ColCount+1;
       For Column := StrGrid.ColCount-1 downto NewColumn do
         StrGrid.Cols[Column].Assign(StrGrid.Cols[Column-1]);
       StrGrid.Cols[NewColumn-1].Text := '';
     end;
    //实现排序操作
     Procedure GridSort(StrGrid: TStringGrid; NoColumn: Integer);
     Var Line, PosActual: Integer;
         Row: TStrings;
     begin
       Renglon := TStringList.Create;
       For Line := 1 to StrGrid.RowCount-1 do
       Begin
         PosActual := Line;
         Row.Assign(TStringlist(StrGrid.Rows[PosActual]));
         While True do
         Begin
           If (PosActual = 0) Or (StrToInt(Row.Strings[NoColumn-1]) >= StrToInt(StrGrid.Cells[NoColumn-1,PosActual-1])) then
           Break;
           StrGrid.Rows[PosActual] := StrGrid.Rows[PosActual-1];
           Dec(PosActual);
         End;
         If StrToInt(Row.Strings[NoColumn-1]) < StrToInt(StrGrid.Cells[NoColumn-1,PosActual]) then
           StrGrid.Rows[PosActual] := Row;
       End;
       Renglon.Free;
     end;


    TstringGrid 的行列合并研究
    unit Unit1;
    //建立一工程,
    //粘贴本单元代码即可看 STringGrid 行列合并效果
    //但发现非固定行非固定列的合并效果不好
    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, Db, ADODB, DBTables, Grids;//注意这里要引用
    type
    TForm1 = class(TForm)
     procedure FormCreate(Sender: TObject);
     procedure SGDrawCell(Sender: TObject; ACol, ARow: Integer;
       Rect: TRect; State: TGridDrawState);
     procedure SGTopLeftChanged(Sender: TObject);
    private
     { Private declarations }
    public
     { Public declarations }
    end;
    var
    Form1: TForm1;
    implementation
    {$R *.DFM}
    // 以下 StringGrid 为固定行,固定列的合并所必须进行的处理
    // 非固定行,非固定列的合并效果不好
    var
    sg:TStringGrid;
    procedure TForm1.FormCreate(Sender: TObject);
    var
    i,j:integer ;
    begin
    Sg:=TStringGrid.Create(self);
    with SG do
    begin
     parent:=self;
     align:=alclient;
     DefaultDrawing:=false;
     FixedColor:=clYellow;
     RowCount:=30;
     ColCount:=20;
     FixedCols:=1;
     FixedRows:=1;
     GridLineWidth:=0;
     Options:=Options+[goEditing]-[goVertLine,goHorzLine,goRangeSelect];
     OnDrawCell:=SGDrawCell;
     OnTopLeftChanged:=SGTopLeftChanged;
     Canvas.Font.name:='宋体';
     Canvas.Font.Size:=10;
     for i:=0 to colCount-1 do
     for j:=0 to RowCount-1 do
       cells[i,j]:=Format('%d行%d列',[j,i]);
     for i:=0 to colCount-1 do
       cells[i,0]:=Format('第%d列',[i]);
     for i:=0 to RowCount-1 do
       cells[0,i]:=Format('第%d行',[i]);
     Cells[0,0]:='   左上角';
     Cells[1,0]:='AA这是列合并BB';
     Cells[0,1]:='A这是行'#10'合并BB';
     Cells[1,1]:='1111111';
     Cells[1,2]:='1111222';
     Cells[2,1]:='2222111';
     Cells[2,2]:='2222222';
    end;
    end;
    //重载 OnDrawCell 事件
    procedure TForm1.SGDrawCell(Sender: TObject; ACol, ARow: Integer;
    Rect: TRect; State: TGridDrawState);
    var
    r:TRect;
    d:TStringGrid;
    s:string;
    ts:TStrings;
    i,n:integer;
    fixed:Boolean;
    begin
    d:=TStringGrid(sender);
    if (Acol=2) and (ARow=0) then
    begin
     r.left:=Rect.left-1-d.colwidths[ACol-1];
     r.top:=rect.top-1;
     r.right:=rect.right;
     r.bottom:=rect.bottom;
     s:=d.cells[ACol-1,ARow];
    end else
    if (Acol=1) and (ARow=0) then
    begin
     r.left:=Rect.left-1;
     r.top:=rect.top-1;
     r.right:=rect.right+d.colwidths[ACol+1];
     r.bottom:=rect.bottom;
     s:=d.cells[ACol,ARow];
    end   //////////以上列合并
    else
    if (Acol=0) and (ARow=2) then
    begin
     r.left:=Rect.left-1;
     r.top:=rect.top-1-d.RowHeights[ARow-1];
     r.right:=rect.right;
     r.bottom:=rect.bottom;
     s:=d.cells[ACol,ARow-1];
    end else
    if (Acol=1) and (ARow=0) then
    begin
     r.left:=Rect.left-1;
     r.top:=rect.top-1;
     r.right:=rect.right;
     r.bottom:=rect.bottom+d.RowHeights[ARow+1];
     s:=d.cells[ACol,ARow];
    end  ////////以上为行合并
    else
    begin
     r.left:=Rect.left-1;
     r.top:=rect.top-1;
     r.right:=rect.right;
     r.bottom:=rect.bottom;
     s:=d.cells[ACol,ARow];
    end;
    d.Canvas.brush.color:=d.color;
    d.canvas.Font.color:=$ff0000;
    Fixed:=false;
    if (Arow<d.FixedRows) or (ACol<d.Fixedcols) then
    begin
     d.Canvas.brush.color:=d.FixedColor;
     d.Canvas.Font.color:=$ff00ff;
     Fixed:=True;
     //d.Canvas.Font.style:=d.Canvas.Font.style+[fsBold];
    end;
    if gdfocused in state then
    begin
     d.canvas.Brush.color:=$00ff00;
    end;
    if fixed then
    begin
     d.Canvas.Pen.color:=$0;
     d.canvas.Rectangle(r);
     d.Canvas.Pen.color:=$f0f0f0;
     d.Canvas.Pen.Width:=2;
     d.canvas.Moveto(r.left+1,r.top+2);
     d.canvas.Lineto(r.left+r.right,r.top+2);
     d.Canvas.Pen.color:=$808080;
     d.Canvas.Pen.Width:=1;
     d.canvas.Moveto(r.Left+1,r.bottom-1);
     d.canvas.Lineto(r.left+r.right,r.bottom-1);
    end else
    begin
     d.Canvas.Pen.color:=$0;
     d.Canvas.Pen.Width:=1;
     d.canvas.Rectangle(r);
    end;
    n:=r.top+4;
    ts:=TStringList.Create;
    ts.CommaText:=s;
    for i:=0 to ts.Count-1 do
    begin
     d.canvas.Textout(r.left+4,n,ts[i]);
     inc(n,d.RowHeights[ARow]);
    end;
    end;
    //重载 OnTopLeftChange事件,特别是行的合并
    procedure TForm1.SGTopLeftChanged(Sender: TObject);
    var
    d:TStringGrid;
    begin
    d:=TStringGrid(Sender);
    d.Cells[0,1]:=d.Cells[0,1];
    d.Cells[0,2]:=d.Cells[0,2];
    end;
    end.
     

  • 相关阅读:
    openssl生成公钥私钥对 加解密
    boost replace_if replace_all_regex_copy用法
    PS 图像滤镜— — USM 锐化
    使用boost库生成 随机数 随机字符串
    改动Android设备信息,如改动手机型号为iPhone7黄金土豪版!
    验证(Verification)与确认(Validation)的差别
    Spring-SpringMVC-Hibernate整合
    全面整理的C++面试题
    Metropolis Hasting算法
    捕捉到来自宇宙深空的神奇X-射线信号
  • 原文地址:https://www.cnblogs.com/xtfnpgy/p/9285425.html
Copyright © 2011-2022 走看看