最近很倒霉:在使用一个安装发布工作时,竟然将我整个文件夹都删除了,可惜我那几个星期的源代码。等我发现时已经过了几天了,无法再找回来了,因此只得再重写代码。现在遇到的问题是DBGrid的拖放问题:设为dmAutomatic,则点击无法移动记录,设为dmManual则在记录上点击时无法响应MouseDown事件,请问哪位大侠能解决  本来这个问题当时我查网上的资料是解决的,也是使用DBGrid,没有来回切换dmManual和dmAutomatic,代码也只有几行,可惜当时顺手拿来没有仔细看。

解决方案 »

  1.   

    在DBGrid上Drag & Drop(拖放)我们在做程序中发现,如果能够让用户将一个Edit的内容直接拖放到一个DBGrid里,会显得很方便,但在程序编制过程中发现,似乎拖放只能拖放到当前的记录上,那假如要拖放到其他记录又怎么办呢,总不能让用户先选择记录,然后再拖放吧。
      后来,通过研究发现,当用鼠标点DBGrid时,DBGrid会自动将记录指针移动到所点击的记录上,这就给了我一个思路,让程序模拟在DBGrid上的一次点击先让光标移动到那条记录上,然后就可以将拖放的数据写入DBgrid里面了。
      通过事实证明这个思路是可行的。下面,我就告诉大家我的做法:
      1) 首先在Form上放一个DBGrid,并它能够显示记录,(这比较简单,就不用多说了)
      2) 在Form上放一个Edit
      3) 修改Edit的属性,把DragMode改为dmAutoMatic, 让用户能够拖放
      4) 在Dbgrid的DragOver事件中增加如下代码: 让它能够接收 Drag & dropprocedure TForm1.DBGrid1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
    begin
    accept:=true;
    end;  5) 在Dbgrid的DragDrop事件中增加如下代码: 让它能够自动跳到光标所指定的记录上procedure TForm1.DBGrid1DragDrop(Sender, Source: TObject; X, Y: Integer);
    begin
    if Source<>Edit1 then exit;
    with Sender as TDbGrid do begin
      Perform(wm_LButtonDown,0,MakeLong(x,y));
      PerForm(WM_LButtonUp, 0,MakeLong(x,y));
      SelectedField.Dataset.edit;
      SelectedField.AsString:=Edit1.text;
    end;
    end;  至此,我们就实现了想要的功能,其中PerForm是TControl的一个通用方法目的是绕过Windows本身的消息循环,而将消息直接发给要发的Control,其具体使用方法请参考Delphi的帮助。 
      

  2.   

    to  meiqingsong(阿飛):我现在需要将DBGrid的记录向TreeView上拖,但设为dmManual则在记录上点击时无法响应MouseDown事件。你的办法是送出了MouseDown消息,但我又需要在什么地方去调用DBGrid1.Perform(wm_LButtonDown,0,0)?这可能与用户习惯很不一样,上次我实现时好象没这么复杂
      

  3.   

    楼主在误删的情况下应该首先进行恢复的尝试,其实在误删后马上进行恢复是很容易的。这方面的工具有:easyrecover,r-studio等。
      

  4.   

    真的没有兄弟在DBGrid中做过拖放编程?
      

  5.   

    这是我在网上找的代码,经测试非常不错:
    procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if <font color=red>ssLeft in Shift</font> then
        TDBGrid(Sender).BeginDrag(False);
    end;procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    begin
      Accept := Source is TDBGrid;
    end;procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    var
      AnItem: TTreeNode;
      I: Integer;
      S: String;
    begin
      with Sender as TTreeView do
      begin
        AnItem := GetNodeAt(X, Y);
        with Source as TDBGrid do
        begin
          S := '';
          for I := 0 to Columns.Count - 1 do
            S := S + Columns[I].Field.AsString + ' ';
        end;
        Items.AddChild(AnItem, S);
        AnItem.Expand(True);
      end;
    end;
      

  6.   

    这是我在网上找的代码,经测试非常不错:
    procedure TForm1.DBGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if ssLeft in Shift then
        TDBGrid(Sender).BeginDrag(False);
    end;procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    begin
      Accept := Source is TDBGrid;
    end;procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
    var
      AnItem: TTreeNode;
      I: Integer;
      S: String;
    begin
      with Sender as TTreeView do
      begin
        AnItem := GetNodeAt(X, Y);
        with Source as TDBGrid do
        begin
          S := '';
          for I := 0 to Columns.Count - 1 do
            S := S + Columns[I].Field.AsString + ' ';
        end;
        Items.AddChild(AnItem, S);
        AnItem.Expand(True);
      end;
    end;