Mirror

How to rearrange items within a TListBox (Views: 12)


Problem/Question/Abstract:

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:

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

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  DropIndex: Integer;
begin
  DropIndex := ListBox1.ItemAtPos(Point(X, Y), True);
  ListBox1.Items.Exchange(ListBox1.ItemIndex, DropIndex);
end;

Solve 2:

There is no build-in method. Try that:


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

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  iTemp: integer;
  ptTemp: TPoint;
  szTemp: string;
begin
  { change the x, y coordinates into a TPoint record }
  ptTemp.x := x;
  ptTemp.y := y;
  { Use a while loop instead of a for loop due to items possible being removed
   from listboxes this prevents an out of bounds exception }
  iTemp := 0;
  while iTemp <= TListBox(Source).Items.Count - 1 do
  begin
    { look for the selected items as these are the ones we wish to move }
    if TListBox(Source).selected[iTemp] then
    begin
      { use a with as to make code easier to read }
      with Sender as TListBox do
      begin
        { need to use a temporary variable as when the item is deleted the indexing will change }
        szTemp := TListBox(Source).items[iTemp];
        { delete the item that is being dragged  }
        TListBox(Source).items.Delete(iTemp);
        { insert the item into the correct position in the listbox that it was dropped on }
        items.Insert(itemAtPos(ptTemp, true), szTemp);
      end;
    end;
    inc(iTemp);
  end;
end;

<< Back to main page