c#从列表框中拖放
本文关键字:拖放 列表 | 更新日期: 2023-09-27 18:14:10
我试图构建一个简单的界面,允许用户将文件放入listBox
以将它们添加到进程中,并将它们拖出以删除它们。一切都很好,但我想添加一个功能,使它更复杂一点。
现在,我将物品的移除与DragLeave
事件绑定在一起,这意味着只要鼠标离开盒子,物品就会被移除。但我希望用户能够改变他们的想法。换句话说,如果他们意识到他们拖出了错误的文件,我希望他们能够将鼠标移回listBox
并释放鼠标以取消操作。我认为这意味着我需要能够捕获MouseUp
事件而不是DragLeave
事件。但到目前为止还没有成功。
下面是我目前用来删除拖出文件的代码。我如何修改,以保持文件从列表中删除,直到用户让鼠标按钮去?
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (listBox1.Items.Count == 0)
{
return;
}
int index = listBox1.IndexFromPoint(e.X, e.Y);
string s = listBox1.Items[index].ToString();
DragDropEffects dde1 = DoDragDrop(s, DragDropEffects.All);
}
private void listBox1_DragLeave(object sender, EventArgs e)
{
ListBox lb = sender as ListBox;
lb.Items.Remove(lb.SelectedItem);
}
编辑2013/05/16
到目前为止,评论和回答都很有用,但我意识到我的问题还不够清楚。在这种情况下,我显示一个与父窗体分离的对话框,基本上与listBox
一样大。当某人从列表中拖出一个文件时,他们是将该文件完全拖出表单。我这样做是不是把自己逼到了死角?我知道我让事情变得更困难了,但如果可能的话,我还是想看看它是如何工作的。
这里有一个相当快速的hack方法来获得您想要的功能:
public object lb_item = null;
private void listBox1_DragLeave(object sender, EventArgs e)
{
ListBox lb = sender as ListBox;
lb_item = lb.SelectedItem;
lb.Items.Remove(lb.SelectedItem);
}
private void listBox1_DragEnter(object sender, DragEventArgs e)
{
if (lb_item != null)
{
listBox1.Items.Add(lb_item);
lb_item = null;
}
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
lb_item = null;
if (listBox1.Items.Count == 0)
{
return;
}
int index = listBox1.IndexFromPoint(e.X, e.Y);
string s = listBox1.Items[index].ToString();
DragDropEffects dde1 = DoDragDrop(s, DragDropEffects.All);
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
lb_item = null;
}
每次用户从框中拖出一个项目时,它都会被暂时保存,直到用户将其放到其他地方或将鼠标放在列表中的新项目上。注意,其中重要的部分是检测用户何时何地放开鼠标,这是处理listBox1
的父节点Form1
的DragDrop
事件的基本原理。
根据布局其余部分的复杂程度和密度,您处理DragDrop
的位置可能会有很大不同。这就是为什么它有点"hacky",但它也很简单。但是,在哪里或多少次将lb_item
为空并不重要,因为它只属于特定的ListBox
。
我想另一种方法是跟踪用户的鼠标状态并采取相应的行动,如果无法处理大量的DragDrop
内容,这可能更适合您。
foreach
和编程附加一个处理程序的拖放事件到该控件,然后删除它完成后…但这可能有点疯狂。我肯定有人有更好的办法。