如何拖动   listview 的行到想要的位置???????????listview 的 类型设为 vsreport , 现在我想 用鼠标 按住 某一行,进行拖动到想要的位置, 例如:按住 第一行 ,拖动到第三行的位置!!!
请问如何实现???

解决方案 »

  1.   

    发三段程序你自己看看吧
    要把LISTVIEW DRAGMODE 设置为DMAUTOMATIC 
    procedure TOperatorEdit.ListView1DragDrop(Sender, Source: TObject; X,  //列表拖放释放
      Y: Integer);
    var
        targetitem,sourceitem:Tlistitem;
    begin
        targetitem:=listview1.GetItemAt(x,y);
        sourceitem:=listview1.selected;    listview1.items.beginupdate;
        try
          moveitem(listview1,sourceitem,targetitem);
          reslist:=targetitem.Index+1;
          refreshbtn.Click;
        finally
          listview1.items.endupdate; //重新设置
        end;end;procedure TOperatorEdit.ListView1DragOver(Sender, Source: TObject; X,    //列表拖放
      Y: Integer; State: TDragState; var Accept: Boolean);
    var 
      targetitem,sourceitem:Tlistitem;
    begin
      targetitem:=listview1.GetItemAt(x,y);
     if (Source=Sender) and (targetitem<>nil) and (treeview1.Selected.HasChildren=false) then
      begin
        Accept:=true;
        sourceitem:=listview1.selected;
        if (targetitem = sourceitem) then Accept:=false;
      end
      else
      begin
         Accept:=false;
      end;
    end;
    procedure TOperatorEdit.moveitem(listview:Tlistview;sourceitem,targeitem:Tlistitem);
    var
      _nodeid:integer;
      i:integer;
    begin
        if targeitem.Index<sourceitem.Index then //目标节点在源节点之上
        begin
           _nodeid:=pinteger(sourceitem.Data)^;
           doperator.Locate('nodeid',_nodeid,[]);
           doperator.Edit;
           doperator['operindex']:=targeitem.Index+1;       i:=targeitem.Index;
           while(i<sourceitem.Index) do
           begin
                _nodeid:=pinteger(listview.Items[i].Data)^;
                doperator.Locate('nodeid',_nodeid,[]);
                doperator.Edit;
                doperator['operindex']:=listview.Items[i].Index+2;
                i:=i+1;
           end;
        end
        else
        begin //目标节点在源节点之下
           _nodeid:=pinteger(sourceitem.Data)^;
           doperator.Locate('nodeid',_nodeid,[]);
           doperator.Edit;
           doperator['operindex']:=targeitem.Index+1;       i:=targeitem.Index;
           while(i>sourceitem.Index) do
           begin
                _nodeid:=pinteger(listview.Items[i].Data)^;
                doperator.Locate('nodeid',_nodeid,[]);
                doperator.Edit;
                doperator['operindex']:=listview.Items[i].Index;
                i:=i-1;
           end;
        end;
        doperator.UpdateBatch();
    end;要把LISTVIEW DRAGMODE 设置为DMAUTOMATIC
      

  2.   

    请问 doperator 是不是 clientdataset 控件 ????  doperator  需要哪些数据???  能不能给出完整的代码???谢谢
      

  3.   

    设置ListView的FullDrag属性为True就可以拖动了
      

  4.   

    FullDrag 根本不行呀!!!  没有人知道吗??
      

  5.   

    这里是一段TListBox的托拽程序,虽然和你要求的TListView不同,但是原理是一样的,只要把ItemAtPos函数换成GetItemAt函数就行了,具体的交换操作再修改一下。不知道对你有没有帮助。type
      TForm1 = class(TForm)
        lb: TListBox;
        procedure lbMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure lbDragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
        procedure lbDragDrop(Sender, Source: TObject; X, Y: Integer);    
      private
        pt: TPoint;
        orignalPos, targetPos: integer;
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}procedure TForm1.lbMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if Button = mbLeft then
      begin
        pt.X := X;
        pt.Y := Y;
        orignalPos := lb.ItemAtPos(pt, true);
        if orignalPos = -1 then
        begin
          showmessage('Here have nothing to drag');
          exit;
        end;
        lb.BeginDrag(False);
      end;
    end;procedure TForm1.lbDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    begin
      if Source is TListBox then
        Accept := true;
    end;procedure TForm1.lbDragDrop(Sender, Source: TObject; X, Y: Integer);
    begin
      pt.X := X;
      pt.Y := Y;
      targetPos := lb.ItemAtPos(pt, false); // return MaxIndex+1 if drop far behind
      if targetPos <= lb.Items.Count-1 then
        lb.Items.Exchange(orignalPos, targetPos)
      else begin
        lb.Items.Append(lb.Items.Strings[orignalPos]);
        lb.Items.Delete(orignalPos);
      end;
    end;
      

  6.   

    这样子你看行不行,改成TListView了type
      TForm1 = class(TForm)
        lv: TListView;
        procedure lvMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure lvDragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
        procedure lvDragDrop(Sender, Source: TObject; X, Y: Integer);
      private
        orignalPos: integer;
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}procedure TForm1.lvMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if Button = mbLeft then
      begin
        orignalPos := lv.GetItemAt(X, Y).Index;
        lv.BeginDrag(False);
      end;
    end;procedure TForm1.lvDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    begin
      if Source is TListView then
        Accept := true;
    end;procedure TForm1.lvDragDrop(Sender, Source: TObject; X, Y: Integer);
    var tempListItem: TListItem;
    begin
      tempListItem := lv.GetItemAt(X, Y);
      lv.Items.Item[lv.GetItemAt(X, Y).Index] := lv.Items.Item[orignalPos];
      lv.Items.Item[orignalPos] := tempListItem;
    end;
      

  7.   

    zousoft(菜菜鸟的战斗诗歌)  不行呀, 拖放后会把 目标的行 复盖 掉 !!!!  没有重新排序!!
      

  8.   

    那应该是交换部分出了问题,真奇怪,怎么不行呢?ListView没有现成的Item交换函数,帮你顶吧
      

  9.   

    呕,我知道,不能用:=赋值,那个只是指针引用。应该用Assign(),TItemList已经重载了这个函数,把所有:=都换成Assign()应该就可以了。
      

  10.   

    修改一下这个函数,应该就没问题了:procedure TForm1.lvDragDrop(Sender, Source: TObject; X, Y: Integer);
    var tempListItem: TListItem;
    begin
      tempListItem := TListItem.Create(lv.Items);
      tempListItem.Assign(lv.GetItemAt(X, Y));
      lv.Items.Item[lv.GetItemAt(X, Y).Index].Assign(lv.Items.Item[orignalPos]);
      lv.Items.Item[orignalPos].Assign(tempListItem);
      tempListItem.Free;
    end;至于你说的排序也许应该调用某个函数刷新一下,说实话,TListView我还真的很少用,不太熟悉。不过相信这个问题应该不难解决。