2012-02-07 99 views
3

我需要拖放我的Tlistbox內的多個項目。
我這裏指的是代碼是德爾福listbox拖放多個項目

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

爲什麼我想這是因爲有一定的順序對應於這些列表框項目。 因此,不是隻需手動選擇每個項目並拖放它,我想要啓用多個拖放。

任何意見,我該如何實現這一點表示讚賞。
也可以建議使用其他組件,如果以下可能使用相同的。

回答

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; 

現在,它是可能的一系列調用Move要做到這一點,但它很難得到它的權利。每次您進行移動時,所選項目的所有索引都會更改。上面給出的方法是我解決這個問題的首選方法。順便提一下,我最近在樹視圖的上下文中研究了完全相同的問題,在這裏也非常棘手!

+0

您正在使用以前版本的代碼。錯誤現在已修復。就像我說的,要想得到正確的令人驚訝的棘手問題! – 2012-02-07 13:39:07

+0

非常感謝! :) – Shirish11 2012-02-09 07:50:47