Delphi: Shift-Up и Shift-Down в списке - PullRequest
4 голосов
/ 13 марта 2011

Есть ли в элементе управления Listview функция для перемещения элементов вверх и вниз?

Ответы [ 2 ]

4 голосов
/ 13 марта 2011

Не слишком много работая с TListView (я в основном использую сетки баз данных), я воспользовался вашим вопросом как возможностью чему-то научиться.Следующий код является результатом, он более визуально ориентирован, чем ответ Дэвида.У него есть некоторые ограничения: он будет перемещать только первый выбранный элемент, и пока он перемещается, отображение для vsIcon и vsSmallIcon выглядит странно после перемещения.

procedure TForm1.btnDownClick(Sender: TObject);
var
  Index: integer;
  temp : TListItem;
begin
  // use a button that cannot get focus, such as TSpeedButton
  if ListView1.Focused then
    if ListView1.SelCount>0 then
    begin
      Index := ListView1.Selected.Index;
      if Index<ListView1.Items.Count then
      begin
        temp := ListView1.Items.Insert(Index+2);
        temp.Assign(ListView1.Items.Item[Index]);
        ListView1.Items.Delete(Index);
        // fix display so moved item is selected/focused
        ListView1.Selected := temp;
        ListView1.ItemFocused := temp;
      end;
    end;
end;

procedure TForm1.btnUpClick(Sender: TObject);
var
  Index: integer;
  temp : TListItem;
begin
  // use a button that cannot get focus, such as TSpeedButton
  if ListView1.Focused then
    if ListView1.SelCount>0 then
    begin
      Index := ListView1.Selected.Index;
      if Index>0 then
      begin
        temp := ListView1.Items.Insert(Index-1);
        temp.Assign(ListView1.Items.Item[Index+1]);
        ListView1.Items.Delete(Index+1);
        // fix display so moved item is selected/focused
        ListView1.Selected := temp;
        ListView1.ItemFocused := temp;
      end;
    end;
end;
3 голосов
/ 13 марта 2011

У вас есть два варианта:

  • Удалите их, а затем снова вставьте их в новом месте.
  • Используйте представление виртуального списка и переместите их в структуру данных.

Моя процедура для выполнения первого из этих параметров выглядит следующим образом:

procedure TBatchTaskList.MoveTasks(const Source: array of TListItem; Target: TListItem);
var
  i, InsertIndex: Integer;
begin
  Assert(IsMainThread);
  BeginUpdate;
  Try
    //work out where to move them
    if Assigned(Target) then begin
      InsertIndex := FListItems.IndexOf(Target);
    end else begin
      InsertIndex := FListItems.Count;
    end;

    //create new items for each moved task
    for i := 0 to high(Source) do begin
      SetListItemValues(
        FListItems.Insert(InsertIndex+i),
        TBatchTask(Source[i].Data)
      );
      Source[i].Data := nil;//handover ownership to the new item
    end;

    //set selection and focus item to give feedback about the move
    for i := 0 to high(Source) do begin
      FListItems[InsertIndex+i].Selected := Source[i].Selected;
    end;
    FBatchList.ItemFocused := FListItems[InsertIndex];

    //delete the duplicate source tasks
    for i := 0 to high(Source) do begin
      Source[i].Delete;
    end;
  Finally
    EndUpdate;
  End;
end;

Метод SetListItemValues используется для заполнения столбцов представления списка.

Это прекрасный пример того, почему виртуальные элементы управления так хороши.

...