Author: Tomas Rutkauskas
Can someone point me to a document on how to drag items around (reposition) within
a TListbox?
Answer:
Solve 1:
It is easier than you might think. Set the DragMode property to dmAutomatic, then
provide these event-handlers for OnDragDrop and OnDragOver:
1
2 procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
3 State: TDragState; var Accept: Boolean);
4 begin
5 Accept := (Sender = Source);
6 end;
7
8 procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
9 var
10 DropIndex: Integer;
11 begin
12 DropIndex := ListBox1.ItemAtPos(Point(X, Y), True);
13 ListBox1.Items.Exchange(ListBox1.ItemIndex, DropIndex);
14 end;
Solve 2:
There is no build-in method. Try that:
15
16 procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
17 State: TDragState; var Accept: Boolean);
18 begin
19 Accept := Sender is TListBox;
20 end;
21
22 procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
23 var
24 iTemp: integer;
25 ptTemp: TPoint;
26 szTemp: string;
27 begin
28 { change the x, y coordinates into a TPoint record }
29 ptTemp.x := x;
30 ptTemp.y := y;
31 { Use a while loop instead of a for loop due to items possible being removed
32 from listboxes this prevents an out of bounds exception }
33 iTemp := 0;
34 while iTemp <= TListBox(Source).Items.Count - 1 do
35 begin
36 { look for the selected items as these are the ones we wish to move }
37 if TListBox(Source).selected[iTemp] then
38 begin
39 { use a with as to make code easier to read }
40 with Sender as TListBox do
41 begin
42 { need to use a temporary variable as when the item is deleted the indexing
43 will change }
44 szTemp := TListBox(Source).items[iTemp];
45 { delete the item that is being dragged }
46 TListBox(Source).items.Delete(iTemp);
47 { insert the item into the correct position in the listbox that it was
48 dropped on }
49 items.Insert(itemAtPos(ptTemp, true), szTemp);
50 end;
51 end;
52 inc(iTemp);
53 end;
54 end;
|