Delphi列表框拖放多个项目

标签 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; 

from here .
它工作正常,但我需要实现的是这样的 enter image description here .

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

任何有关我如何实现这一目标的意见都将受到赞赏。
如果可以使用其他组件,也可以建议使用其他组件。

最佳答案

要做好这一点是非常棘手的(请参阅我对此答案的第一次修订,了解如何出错的示例)。

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

  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;

现在,可以通过一系列 Move 调用来完成此操作,但很难做到正确。每次移动时,所选项目的所有索引都会发生变化。我上面给出的方法是我解决这个问题的首选方法。顺便说一句,我最近在 TreeView 的上下文中解决了完全相同的问题,而且这也非常棘手!

关于Delphi列表框拖放多个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9176684/

相关文章:

德尔福: force unload injected module

c# - ListBox 和 Checkbox 中存在大量数据的奇怪行为 [提供的最小项目]

c# - MVVM 列表框项上下文菜单

wpf - 从绑定(bind)到 xml 的按钮样式列表框中获取单击的按钮内容

delphi - 找不到文件xxxxx.dcu

c++ - MFC 应用程序中 Delphi 7 和 Delphi XE4 之间的 ActiveX 差异

delphi - IDAPI、BdeAdmin 和 Windows 7

javascript - 如何处理来自其他网站的 "semi-image"URL ("images"的放置事件)

JavaScript 模块模式和拖放 API

iOS 11 dropInteraction performDrop 文件