Delphi列表框拖放多个项目

Shi*_*h11 3 delphi drag-and-drop listbox delphi-xe

我需要在我的内部拖放多个项目Tlistbox.
我所指的代码是

var 
   StartingPoint : TPoint;

implementation

...

procedure TForm1.FormCreate(Sender: TObject) ;
begin
   ListBox1.DragMode := dmAutomatic;
end;

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer) ;
var
   DropPosition, StartPosition: Integer;
   DropPoint: TPoint;
begin
   DropPoint.X := X;
   DropPoint.Y := Y;
   with Source as TListBox do
   begin
     StartPosition := ItemAtPos(StartingPoint,True) ;
     DropPosition := ItemAtPos(DropPoint,True) ;

    Items.Move(StartPosition, DropPosition) ;
   end;
end;

procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer; State:  TDragState; var Accept: Boolean) ;
begin
    Accept := Source = ListBox1;
end;

procedure TForm1.ListBox1MouseDown(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer) ;
begin
    StartingPoint.X := X;
    StartingPoint.Y := Y;
end; 
Run Code Online (Sandbox Code Playgroud)

从这里开始.
它工作正常但我需要实现的是这样的 在此输入图像描述.

为什么我想要这是因为有一些与这些列表框项目相对应的顺序.因此,我不想手动选择每个项目并拖放它,而是想要启用多个拖放.

关于如何实现这一点的任何观点表示赞赏.
如果可以使用其他组件,也可以建议使用其他组件.

Dav*_*nan 6

这样做起来非常棘手(请参阅我对此答案的第一次修订以获取如何解决错误的示例).

这是一个相当容易理解的方法,通过以下方式解决问题:

  1. 从列表中删除所有选定的项目并将其存储在临时字符串列表中.
  2. 从目标索引开始将项重新添加到列表中.
  3. 重新选择每个重新添加的项目.

 

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  ListBox: TListBox;
  i, TargetIndex: Integer;
  SelectedItems: TStringList;
begin
  Assert(Source=Sender);
  ListBox := Sender as TListBox;
  TargetIndex := ListBox.ItemAtPos(Point(X, Y), False);
  if TargetIndex<>-1 then
  begin
    SelectedItems := TStringList.Create;
    try
      ListBox.Items.BeginUpdate;
      try
        for i := ListBox.Items.Count-1 downto 0 do
        begin
          if ListBox.Selected[i] then
          begin
            SelectedItems.AddObject(ListBox.Items[i], ListBox.Items.Objects[i]);
            ListBox.Items.Delete(i);
            if i<TargetIndex then
              dec(TargetIndex);
          end;
        end;

        for i := SelectedItems.Count-1 downto 0 do
        begin
          ListBox.Items.InsertObject(TargetIndex, SelectedItems[i], SelectedItems.Objects[i]);
          ListBox.Selected[TargetIndex] := True;
          inc(TargetIndex);
        end;
      finally
        ListBox.Items.EndUpdate;
      end;
    finally
      SelectedItems.Free;
    end;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

现在,可以通过一系列调用来实现这一点,Move但很难做到正确.每次移动时,所选项目的所有索引都会更改.我上面给出的方法是我解决这个问题的首选方法.顺便说一句,我最近在树视图的上下文中处理了完全相同的问题,而且它也非常棘手!