Проблемы перетаскивания TListBox с включенным MultiSelect - PullRequest
2 голосов
/ 11 октября 2008

У меня есть TListBox с множественным выбором и ExtendedSelect, оба установлены в true. Мне нужно иметь возможность перетаскивать несколько элементов в списке, чтобы переставить их. Моя проблема в том, что происходит, когда пользователь нажимает на элемент, который уже выбран, не удерживая нажатой клавишу CTRL или SHIFT.

Случай 1: DragMode установлен в dmManual Выбор очищается до нажатия мыши. Это не позволит перетаскивать несколько элементов.

Случай 2: DragMode установлен в dmAutomatic Событие MouseDown никогда не срабатывает. Выбор не очищен, поэтому перетаскивание в порядке, но пользователь не может очистить выбор, щелкнув один из выбранных элементов. Это действительно создает проблему, если все элементы выбраны или следующий элемент, который пользователь хочет выбрать, был частью текущего выбора.

Обратите внимание, что эта проблема возникает только в том случае, если вы назначаете объект DragObject в процедуре OnStartDrag. Я думаю, что проблема исчезнет, ​​если OnStartDrag будет запускаться только после того, как пользователь перемещает мышь. У меня Mouse.DragImmediate: = false, но я все равно получаю StartDrag, как только нажимаю на элемент в списке.

Я использую Delphi 7 для этого проекта, но я вижу то же поведение в Delphi 2007.

Ответы [ 4 ]

0 голосов
/ 22 января 2009

Немного клуджа, но это работает. DragMode в ListBox установлен на dmAutomatic.

procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
  iDropIdx, i: Integer;
  pDropPoint: TPoint;
  slSelected: TStrings;
begin
  {Which item is being dropped onto?}
  pDropPoint := Point(X, Y);
  iDropIdx := ListBox1.ItemAtPos(pDropPoint, False);

  slSelected := TStringList.Create;
  try
    {Copy the selected items to another string list}
    for i := 0 to Pred(ListBox1.Items.Count) do
    begin
      if (ListBox1.Selected[i]) then
        slSelected.Append(ListBox1.Items[i]);
    end;

    {Find the selected items in the listbox and swap them with the drop target}
    for i := 0 to Pred(slSelected.Count) do
    begin
      ListBox1.Items.Exchange(ListBox1.Items.IndexOf(slSelected[i]), iDropIdx);
      inc(iDropIdx);
    end;
  finally
    slSelected.Free;
  end;
end;
0 голосов
/ 21 октября 2008

Я не уверен, почему это имеет значение, но если я изменяю DragObject на TDrag Control ObjectEx (вместо TDragObjectEx), я получаю искомое поведение. Режим перетаскивания установлен на Автоматический.

Я пытался посмотреть и посмотреть, что это влияет, но я не мог понять это.

0 голосов
/ 28 декабря 2008

Вариант использования 2 и при возникновении события TListBox.OnMouseUp проверяется, выбраны ли несколько элементов и были ли они перемещены. Если несколько элементов выбраны, но не были перетащены, отмените выбор всех элементов, кроме выбранного элемента.

Я бы использовал этот метод, потому что Windows Explorer работает таким образом.

0 голосов
/ 11 октября 2008

Я играл с этим некоторое время. И наблюдайте те же эффекты.

Я бы использовал Case2 и добавил бы кнопку (Выбрать все / Отменить все) в список. Он даже добавляет дополнительные функциональные возможности и решает наиболее неприятную часть проблемы.

...