拖动多个文件
Drag multiple files
我有一个包含文件路径列表的列表框,其中 属性 SelectionMode
设置为 MultiExtended
。因此,我可以 select 此列表中的许多项。
现在,我想从目标文件夹中的这些路径开始拖放文件。
我的代码:
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);
}
如果我 select 并将 1 个单曲 line/file 从 ListBox 拖放到目标文件夹,它就完美了。
相反,如果我执行多个 selection 并尝试拖放,它只能 select 我开始拖动的那一行。似乎 MouseDown
阻止了这个?
你会如何解决这个问题?
是的...我认为没有解决该问题的好方法。当您再次单击以启动拖动时,它将切换该项目。在鼠标 按住并移动 .
之前,我们不知道用户实际上想要进行拖动
一个可能的解决方案是从其他东西启动 drag/drop,只是以某种方式真正清楚地表明用户应该拖动什么。这里我使用的是标签而不是列表框:
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!");
}
}
}
您必须对鼠标按下和鼠标移动活动挑剔。当它位于列表框的图形矩形内时,您将需要正常的行为。当它超出此矩形的边界时,您将需要 drag/drop 功能。您可以试试下面的伪代码:
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
}
使用 ListBox
执行此操作似乎非常困难。其实我还没有找到解决办法..
改用ListView
!这很容易,使用 ItemDrag
事件,并且是 更好的 控件。我无法计算我必须从 [=30= 更改的频率] ListBox
到 ListView
因为我需要这个或那个 'little' 额外的..
您的代码已移至 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 有趣的文章提出了解决方案。也许你不需要它,因为你已经说过你已经复制了一个已经工作的文件..
我有一个包含文件路径列表的列表框,其中 属性 SelectionMode
设置为 MultiExtended
。因此,我可以 select 此列表中的许多项。
现在,我想从目标文件夹中的这些路径开始拖放文件。
我的代码:
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);
}
如果我 select 并将 1 个单曲 line/file 从 ListBox 拖放到目标文件夹,它就完美了。
相反,如果我执行多个 selection 并尝试拖放,它只能 select 我开始拖动的那一行。似乎 MouseDown
阻止了这个?
你会如何解决这个问题?
是的...我认为没有解决该问题的好方法。当您再次单击以启动拖动时,它将切换该项目。在鼠标 按住并移动 .
之前,我们不知道用户实际上想要进行拖动一个可能的解决方案是从其他东西启动 drag/drop,只是以某种方式真正清楚地表明用户应该拖动什么。这里我使用的是标签而不是列表框:
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!");
}
}
}
您必须对鼠标按下和鼠标移动活动挑剔。当它位于列表框的图形矩形内时,您将需要正常的行为。当它超出此矩形的边界时,您将需要 drag/drop 功能。您可以试试下面的伪代码:
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
}
使用 ListBox
执行此操作似乎非常困难。其实我还没有找到解决办法..
改用ListView
!这很容易,使用 ItemDrag
事件,并且是 更好的 控件。我无法计算我必须从 [=30= 更改的频率] ListBox
到 ListView
因为我需要这个或那个 'little' 额外的..
您的代码已移至 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 有趣的文章提出了解决方案。也许你不需要它,因为你已经说过你已经复制了一个已经工作的文件..