2

我有一个带有多选和 ExtendedSelect 的 TListBox 都设置为 true。我需要能够拖动列表框中的多个项目来重新排列它们。我的问题是当用户单击已选择的项目而不按住 CTRL 或 SHIFT 键时会发生什么。

案例一:DragMode 设置为 dmManual 在鼠标按下之前清除选择。这将不允许拖动多个项目。

情况 2:DragMode 设置为 dmAutomatic MouseDown 事件从不触发。选择未清除,因此可以拖动,但用户无法通过单击所选项目之一来清除选择。如果选择了所有项目或者用户想要选择的下一个项目是当前选择的一部分,这确实会导致问题。

请注意,仅当您在 OnStartDrag 过程中为 DragObject 分配某些内容时,才会出现此问题。我认为如果 OnStartDrag 仅在用户移动鼠标后启动,问题就会消失。我设置了 Mouse.DragImmediate := false ,但是只要单击列表框中的某个项目,我仍然会触发 StartDrag。

我在这个项目中使用了 Delphi 7,但我在 Delphi 2007 中看到了相同的行为。

4

4 回答 4

0

我已经玩了一段时间了。并观察同样的效果。

我会使用 Case2 并在列表中添加一个(全选/取消全选)按钮。它甚至增加了额外的功能并解决了问题中最烦人的部分。

于 2008-10-11T19:10:07.880 回答
0

我不确定为什么这会有所不同,但如果我将 DragObject 更改为 TDrag Control ObjectEx(而不是 TDragObjectEx),我会得到我正在寻找的行为。拖动模式设置为自动。

我试图看看这会影响什么,但我无法弄清楚。

于 2008-10-21T15:20:35.983 回答
0

用例 2 和 TListBox.OnMouseUp 事件触发时检查是否选择并拖动了多个项目。如果选择了多个项目,但未拖动,则取消选择除单击项目之外的所有项目。

我会使用这种方法,因为 Windows 资源管理器就是这样工作的。

于 2008-12-28T00:55:44.820 回答
0

有点杂乱无章,但这行得通。ListBox 上的 DragMode 设置为 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;
于 2009-01-22T16:27:23.103 回答