【问题标题】:How to drag & drop items in the same ListView?如何在同一个 ListView 中拖放项目?
【发布时间】:2012-02-25 11:47:02
【问题描述】:

考虑这是一个显示文件和文件夹的 ListView,我已经为复制/移动/重命名/显示属性等编写了代码,我只需要最后一件事。如何像在 Windows 资源管理器中一样拖放到同一个 ListView 中,我有移动和复制功能,我只需要获取用户在某个文件夹中放置的项目或以其他方式我需要获取这两个参数来调用 复制功能

void copy(ListViewItem [] droppedItems, string destination path)
{
 // Copy target to destination
}

【问题讨论】:

  • Windows 中的拖放操作可以使用 3 个简单的事件 - DragEnter、DragLeave 和 DragDrop 来实现。请参阅此 Link 了解准确信息....

标签: c# listview drag-and-drop copy listviewitem


【解决方案1】:

首先将列表视图的 AllowDrop 属性设置为 true。实现 ItemDrag 事件以检测拖动的开始。我将使用一个私有变量来确保 D+D 仅在控件内部起作用:

    bool privateDrag;

    private void listView1_ItemDrag(object sender, ItemDragEventArgs e) {
        privateDrag = true;
        DoDragDrop(e.Item, DragDropEffects.Copy);
        privateDrag = false;
    }

接下来你需要 DragEnter 事件,它会立即触发:

    private void listView1_DragEnter(object sender, DragEventArgs e) {
        if (privateDrag) e.Effect = e.AllowedEffect;
    }

接下来,您需要有选择地选择用户可以放置的项目。这需要 DragOver 事件并检查悬停的项目。您需要将代表文件夹的项目与常规的“文件”项目区分开来。一种方法是使用 ListViewItem.Tag 属性。例如,您可以将其设置为文件夹的路径。使这段代码工作:

    private void listView1_DragOver(object sender, DragEventArgs e) {
        var pos = listView1.PointToClient(new Point(e.X, e.Y));
        var hit = listView1.HitTest(pos);
        if (hit.Item != null && hit.Item.Tag != null) {
            var dragItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
            copy(dragItem, (string)hit.Item.Tag);
        }
    }

如果您想支持拖动多个项目,请将您的拖动对象设置为 ListView.SelectedIndices 属性。

【讨论】:

  • 为什么不在 DragOver 事件中选择它?
  • 我认为DragOver事件是为了展示效果,必须有DragDrop事件的处理才能真正放下item。
  • 我不太清楚privateDrag 的目的。这是为了防止拖动项来自ListViewItem以外的其他来源?
猜你喜欢
  • 2016-04-02
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-04
  • 2013-01-05
相关资源
最近更新 更多