【问题标题】:Delphi listbox drag drop multiple itemsDelphi列表框拖放多个项目
【发布时间】:2012-02-28 21:44:56
【问题描述】:

我需要在我的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.
它工作正常,但我需要实现的是这样 .

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

感谢您对如何实现这一目标的任何看法。
如果以下可能使用相同的组件,也可以建议使用其他组件。

【问题讨论】:

    标签: delphi drag-and-drop listbox delphi-xe


    【解决方案1】:

    要做好这件事出人意料地棘手(有关如何弄错的示例,请参阅我对此答案的第一次修订)。

    这是一个相当容易理解的解决问题的方法:

    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 的一系列调用来做到这一点,但很难做到这一点。每次移动时,所选项目的所有索引都会更改。我上面给出的方法是我解决这个问题的首选方法。顺便说一句,我最近在树视图的上下文中解决了完全相同的问题,这也很棘手!

    【讨论】:

    • 您使用的是以前版本的代码。错误现已修复。就像我说的,做对是非常棘手的!
    猜你喜欢
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多