我自己's profile我自己的空间PhotosBlogLists Tools Help

Blog


    January 31

    我也来篇技术贴之二:Delphi中如何实现Shift多选并使用选中的数据

    Delphi中,DBGrid功能是比较弱的,很多功能别的组件本来很容易就能实现,到了DBGrid就变得相当麻烦了。
    很多人都不推荐使用DBGrid了,不过在我刚学的时候,师兄让我用DBGrid,我也没办法,只好硬着头皮做,也总结的点经验。
    Shift多选的问题,在DBGrid中,居然要用到四个事件OnKeyDown,OnKeyUp,OnMouseUp,DataSource1StateChange。真是相当麻烦。能不用还是别用了。
    最关键的是,还要在private里声明三个变量:
    private
        { Private declarations }
          FKeyShift:   Boolean;
          FRecNo: Integer;
          FOldNo: Integer;
    三个事件代码如下:
    //Shift多选
    procedure TMainForm.DBGrid1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
        FKeyShift   :=   ssShift   in   Shift;
    end;

    procedure TMainForm.DBGrid1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      FKeyShift   :=   False;
    end;
    procedure TMainForm.DBGrid1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      I: Integer;
    begin
      if Button <> mbLeft then
        Exit;
      if not TDBGrid(Sender).DataSource.DataSet.Active then
        Exit;
      if FKeyShift then begin
        FRecNo := TDBGrid(Sender).DataSource.DataSet.RecNo;
        if FKeyShift then DBGrid1.SelectedRows.CurrentRowSelected := True;
        if FOldNo = -1 then
          FOldNo := 1;
        if FRecNo > FOldNo then
          for I := FRecNo downto FOldNo do begin
            TDBGrid(Sender).DataSource.DataSet.RecNo := I;
            TDBGrid(Sender).SelectedRows.CurrentRowSelected := True;
          end
        else
          for I := FRecNo to FOldNo do begin
            TDBGrid(Sender).DataSource.DataSet.RecNo := I;
            TDBGrid(Sender).SelectedRows.CurrentRowSelected := True;
          end;
      end
      else//Shift not pressed
        FOldNo := TDBGrid(Sender).DataSource.DataSet.RecNo
    end;

    procedure TMainForm.DataSource1StateChange(Sender: TObject);
    begin
      FOldNo := FRecNo;
      if TDataSource(Sender).DataSet.Active then
      FRecNo := TDataSource(Sender).DataSet.RecNo;
      FKeyShift := False;
    end;
    //shift多选结束
     
    至于使用所选的数据,可以参考一下代码
    var
    k:Integer;
    Name:String;
    begin
      k:=0;
      While k < Mainform.dbgrid1.SelectedRows.Count  do  //判断是否已到选择末尾
          Begin
             Mainform.DBGrid.DataSource.DataSet.GotoBookmark(pointer(Mainform.dbgrid1.SelectedRows.Items[k]));
             //移动到选择的行
             Name:= Mainform.DBGrid1.DataSource.DataSet.FieldByName('name').Value;
             //把DBGrid相关字段的值提取出来,也可以用Fields[]
          end;
    end;

    我也来篇技术贴之一:Delphi里DBGrid如何实现拖拽

    好赖咱也是堂堂计算机专业的,开了快一年的博克了,居然一个技术贴都没贴过,想想真是惭愧,特别是最近查资料经常查到别人的博克里,深感各位高人之慷慨无私。所以我也准备把我这个月的一点编程心得贴上来。
    关于DBGrid如何实现拖拽的问题,我费了好大劲,找了好多网页,最后把两个网页的内容攒到一起才解决的。为什么这么费劲呢?主要是因为DBGrid不响应MouseDown事件,所以不能用一般控件在MouseDown事件里写
      if Button=mbLeft then
      (Sender As TLabel).BeginDrag(False) ;
    来实现了。
    而只能在MouseMove事件里判断鼠标左键是否按下,如果按下开始拖拽。代码是这样的:
    procedure DBGridMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    begin
      if ssLeft in Shift then   //mousemove中判断鼠标左键按下ssLeft是判断左键,右键是ssRight
      (Sender As TDBGrid).BeginDrag(False) ;
    end;