WPF 中的多项选择拖放






3.33/5 (14投票s)
讨论在 ListBox/ListView 中实现多选项目的拖放功能
注意 - 这是我最早的文章之一,我不能保证示例有效且演示清晰。我计划写另一篇文章,将我的早期文章中的示例整合起来,使它们能够运行。感谢您的理解。
引言
这篇文章是之前主题的一个变体:拖放(参见 非常简单的 WPF 拖放示例,无需 Win32 调用)。这里讨论了在 WPF ListView
或 ListBox
中拖放多个选定项目。
Using the Code
要运行此示例,请在 Visual Studio 2008 中打开它。然后只需编译并运行应用程序即可。
关于使用此示例的几点说明
- 您可以通过使用 Ctrl 或 Shift 键与鼠标结合来选择列表中的多个条目。
- 为了启动拖动操作,您必须再次单击一个选定的项目,并在按住鼠标的同时移动鼠标。
- 如果在“拖动”结束时,鼠标指针位于某个选定项目上方,则不会执行任何操作。
- 选定的项目在拖动操作开始时不必连续,但在放下后它们会变得连续。
- 拖放项目的顺序在放下后保持不变。
代码描述
以下是一些代码摘录。在拖动操作开始时调用的函数 ListView1_PreviewMouseLeftButtonDown
中,我们创建一个选定项目的集合 (Dictionary
,值为 null
) 并将其作为数据项传递给 DragDrop.DoDragDrop(...)
函数
Dictionary shapes = new Dictionary();
if (ListView1.SelectedItems.Count == 0)
return;
foreach(Shape shape in ListView1.SelectedItems)
{
shapes[shape] = null;
}
Shape currentShape = ListView1.Items[index] as Shape;
// we do not initiate drag if the mouse descended on
// a non-selected item during the beginning of drag
if (!shapes.ContainsKey(currentShape))
return;
DragDrop.DoDragDrop(this.ListView1, shapes, allowedEffects);
函数 ListView1_Drop
(实现放下操作的函数)稍微复杂一些。首先,我们记录选定项目被放下的列表项
int index = this.GetCurrentIndex(e.GetPosition);
...
Shape dropTargetShape = myShapes[index];
然后,我们构建一个要放下的选定项目列表
List dropList = new List();
foreach(Shape shape in myShapes)
{
if (!selectedShapes.ContainsKey(shape))
continue;
dropList.Add(shape);
}
我们需要此步骤以确保放下项目的顺序与它们最初的顺序相同。(在 ListView.SelectedItems
集合中,项目存储在它们被选定的顺序中,而不是它们在 ListView
中的顺序)。
然后,我们从集合 myShapes
(它是 ListView
项目的集合)中删除所有选定的项目
foreach(Shape shape in dropList)
{
myShapes.Remove(shape);
}
然后,我们获取放下目标项目在修改后的集合中的(可能)新索引
// find index of the drop target item after the removal
// of the items to be dropped
int selectIndex = myShapes.IndexOf(dropTargetShape);
最后,我们将项目插入到放下目标项目之前
for(int i = 0; i < dropList.Count; i++)
{
Shape shape = dropList[i];
myShapes.Insert(i + selectIndex, shape);
...
}
历史
- 2008 年 3 月 5 日:初始发布
- 2008 年 3 月 6 日:添加了屏幕截图