拖动多个文件

时间:2015-07-16 15:48:40

标签: c# .net winforms drag-and-drop listbox

我有一个ListBox,其中包含一个文件路径列表,其属性SelectionMode设置为MultiExtended。因此,我可以从此列表中选择许多项目。

现在,我想从我删除它们的目标文件夹中的那些路径开始拖放文件。

我的代码:

private void Form1_Load(object sender, EventArgs e)
{
    // populate the FileList
    // i.e. FileList.Items.Add("d:/Samples/file-00" + i + ".wav");

    this.FileList.MouseDown += new MouseEventHandler(FileList_MouseDown);
    this.FileList.DragOver += new DragEventHandler(FileList_DragOver);
}

void FileList_DragOver(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Copy;
}

void FileList_MouseDown(object sender, MouseEventArgs e)
{
    List<string> filesToDrag = new List<string>();
    foreach (var item in FileList.SelectedItems)
    {
        filesToDrag.Add(item.ToString().Trim());
    }

    this.FileList.DoDragDrop(new DataObject(DataFormats.FileDrop, 
                             filesToDrag.ToArray()), DragDropEffects.Copy);
}

如果我从ListBox中选择并删除1个单行/文件到目标文件夹,它就完美了。

相反,如果我进行多项选择并尝试拖放,则可以选择我开始拖动的那一行。似乎MouseDown阻止了这个?

你会如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

使用ListBox执行此操作似乎非常困难。实际上我还没有找到解决方案..

使用ListView代替!这很简单,使用ItemDrag事件并且是一个好得多的控件。我无法计算我从一个廉价的&改变的频率#39; ListBoxListView,因为我需要这个或那个小小的&#39;额外..

以下代码移至ItemDrag

private void listView1_ItemDrag(object sender, ItemDragEventArgs e)
{
    List<string> filesToDrag = new List<string>();
    foreach (var item in listView1.SelectedItems)
    {
        filesToDrag.Add(item.ToString().Trim());
    }

    this.listView1.DoDragDrop(new DataObject(DataFormats.FileDrop,
                                filesToDrag.ToArray()), DragDropEffects.Copy);
}

请注意,这只解决了MouseDown更改选择的问题。实际的复制本身并不是一个保证。

我发现this有趣的文章提出了解决方案。也许你不需要它,因为你已经说过你复制了一个已经正常工作的文件..

答案 1 :(得分:0)

是的......我不认为解决这个问题的方法很好。当您再次单击以启动拖动时,它将切换该项目。我们不知道用户实际上想要拖动,直到鼠标按住并移动

一个可能的解决方案是从其他东西启动拖放,只是以某种方式使其非常清楚,这是用户应该拖动的。在这里,我使用Label而不是ListBox:

    void label1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            List<string> filesToDrag = new List<string>();
            foreach (var item in FileList.SelectedItems)
            {
                filesToDrag.Add(item.ToString().Trim());
            }
            if (filesToDrag.Count > 0)
            {
                this.FileList.DoDragDrop(new DataObject(DataFormats.FileDrop,
                                     filesToDrag.ToArray()), DragDropEffects.Copy);
            }
            else
            {
                MessageBox.Show("Select Files First!");
            }
        }
    }

答案 2 :(得分:0)

你必须对鼠标按下和鼠标移动活动感到挑剔。当它在列表框的图形矩形内时,您将需要正常的行为。当它超出此矩形的范围时,您将需要拖放功能。你可以尝试下面的伪代码:

MouseDown(sender, e)
{
    var x = <your sender as control>.ItemFromPoint(.....)
    this.mouseLocation = x == null ? x : e.Location;
}

MouseMove(sender, e)
{
    if control rectangle doesn't contain the current location then
        <your sender as control>.Capture = false
        DoDragDrop
}