首页 > 解决方案 > Delphi树视图多选拖放给出索引超出范围错误

问题描述

我有一个 TTreeview,其中的节点可以指定为文件夹或文件。多选是真的。MultiSelectStyle 包含 msControlSelect 和 msShiftSelect。

如果我选择不连续数量的节点然后拖放到文件夹上,则会出现索引越界错误。

procedure TRoleFrame.tvViewsDragDrop(Sender, Source: TObject; X, Y: Integer);
var
  Src, Dst: TTreeNode;
  LDestIsFolder: boolean;
  i: integer;
begin
  inherited;
  Dst := tvViews.GetNodeAt(X,Y);  // Dst must be assigned due to DragOver below
  LDestIsFolder := Dst.ClassType = TInfoNodeFolder;

  for i := 0 to tvViews.SelectionCount-1 do begin
    Src := tvViews.Selections[i];

    if LDestIsFolder then
      Src.MoveTo(Dst, naAddChild)   //  Add a file to a folder
    else
      Src.MoveTo(Dst, naInsert);
  end;

  FDirty := true;
end;

procedure TRoleFrame.tvViewsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState;
  var Accept: Boolean);
var
  Src, Dst: TTreeNode;
begin
  inherited;
  Src := tvViews.Selected;
  Dst := tvViews.GetNodeAt(X,Y);
  Accept := Assigned(Dst) and Assigned(Src) and (Src <> Dst);
end;

错误发生在 DragDrop 事件中。

for i := 0 to tvViews.SelectionCount-1 do begin

当 for 循环开始时,SelectCount 是正确的。计数 = 实际选择的节点数。例如 5。

第一次 MoveTo 发生后,SelectionCount 始终为 1(意味着 Selections[0] 是唯一有效的节点)

在循环的下一次迭代中 i=1。Selections[1] 超出范围。

因此,一旦选定的节点之一被移动,关于 SelectionCount 和 Selections 的所有赌注似乎都被取消了。

我的问题是,实现多选拖放的正确方法是什么?

提前致谢 :)

标签: delphidrag-and-droptreeviewmulti-select

解决方案


推荐阅读