listview中有很多行,如何拖拽一行或多行来实现移动它们。
另外如何自定义拖拽时的定位标志,像东方影都中的样子(红色箭头)。

解决方案 »

  1.   

    下面代码是操作ListBox的,你参考一下,或许对ListView有用:
    ...
    type
      TForm1 = class(TForm)
        lbFir: TListBox;  {拖动交换节点}
        lbSec: TListBox;  {拖动移动节点}
        procedure lbFirDragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
        procedure lbFirDragDrop(Sender, Source: TObject; X, Y: Integer);
        procedure lbFirEndDrag(Sender, Target: TObject; X, Y: Integer);
        procedure lbSecDragDrop(Sender, Source: TObject; X, Y: Integer);
        procedure lbSecDragOver(Sender, Source: TObject; X, Y: Integer;
          State: TDragState; var Accept: Boolean);
        procedure lbSecEndDrag(Sender, Target: TObject; X, Y: Integer);
    ...
    implementationvar
      oldrect: Trect;{$R *.dfm}procedure TForm1.lbFirDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    var
      mypos:Tpoint;
    begin
      Accept := Source = lbFir;
      mypos.x:=x;
      mypos.y:=y;
      if lbFir.ItemAtPos(mypos,true)<>-1 then
      begin
        lbFir.Canvas.DrawFocusRect(oldrect);   //通过‘异或’去掉上次的框框
        lbFir.Canvas.DrawFocusRect(lbFir.ItemRect(lbFir.ItemAtPos(mypos,true)));//画上本次的框框
        oldrect:=lbFir.ItemRect(lbFir.ItemAtPos(mypos,true));
      end;
    end;procedure TForm1.lbFirDragDrop(Sender, Source: TObject; X, Y: Integer);
    var
      P_move:Tpoint;
    begin
     {通过坐标获得ITEM}
      P_move.x:=x;
      p_move.y:=y;  if (lbFir.itemindex<>-1) and (lbFir.ItemAtPos(P_move,true)<>-1) then
      //这一句可以替换上次那几句
        lbFir.Items.Exchange(lbFir.itemindex,lbFir.ItemAtPos(P_move,true));//互换ITEM  //下面一句也是拖放不成功的时候要去掉最后画的那个FOCUS框
      if lbFir.ItemAtPos(P_move,true)=-1 then
        lbFir.Canvas.DrawFocusRect(oldrect);
    end;procedure TForm1.lbFirEndDrag(Sender, Target: TObject; X, Y: Integer);
    begin
      if (target<>nil)and(target.ClassName<>sender.ClassName) then
        lbFir.Items.Delete(lbFir.itemindex);
      if target=nil then
        lbFir.Canvas.DrawFocusRect(oldrect);
      oldrect.Bottom:=0; //拖放完之后把矩形变量清空
    end;/****************************/procedure TForm1.lbSecDragDrop(Sender, Source: TObject; X, Y: Integer);
    var
      P_move:Tpoint;
    begin
     {通过坐标获得ITEM}
      P_move.x:=x;
      p_move.y:=y;  if (lbSec.itemindex<>-1) and (lbSec.ItemAtPos(P_move,true)<>-1) then
      begin
      //这一句排序
        lbSec.Items.Insert(lbSec.ItemAtPos(P_move,True),lbSec.Items.Strings[lbSec.ItemIndex]);
        lbSec.Items.Delete(lbSec.ItemIndex);
      end;
      //下面一句也是拖放不成功的时候要去掉最后画的那个FOCUS框
      if lbSec.ItemAtPos(P_move,true)=-1 then
        lbSec.Canvas.DrawFocusRect(oldrect);
    end;procedure TForm1.lbSecDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
    var
      mypos:Tpoint;
    begin
      Accept := Source = lbSec;
      mypos.x:=x;
      mypos.y:=y;
      if lbSec.ItemAtPos(mypos,true)<>-1 then
      begin
        lbSec.Canvas.DrawFocusRect(oldrect);   //通过‘异或’去掉上次的框框
        lbSec.Canvas.DrawFocusRect(lbSec.ItemRect(lbFir.ItemAtPos(mypos,true)));//画上本次的框框
        oldrect:=lbSec.ItemRect(lbSec.ItemAtPos(mypos,true));
      end;
    end;procedure TForm1.lbSecEndDrag(Sender, Target: TObject; X, Y: Integer);
    var
      P_move:Tpoint;
    begin
     {通过坐标获得ITEM}
      P_move.x:=x;
      p_move.y:=y;
      if (target<>nil)and(target.ClassName<>sender.ClassName) then
        lbSec.Items.Delete(lbFir.itemindex);
      if target=nil then
        lbSec.Canvas.DrawFocusRect(oldrect);
      if lbSec.ItemAtPos(P_move,True) <> -1 then
        lbSec.Selected[lbSec.ItemAtPos(P_move,True)] := true;
      oldrect.Bottom:=0; //拖放完之后把矩形变量清空
    end;end.