问题描述
我正在尝试构建一个简单的界面,允许用户将文件放入 listBox
以将它们添加到进程中,并将它们拖出以删除它们.一切工作正常,但我想添加一个功能,让它更复杂一点.
I'm trying to build a simple interface that allows users to drop files into a listBox
to add them to a process, and to drag them out to remove them. Everything is working fine, but I'd like to add one feature to make it just a tad more sophisticated.
现在,我删除了与 DragLeave
事件相关的项目,这意味着只要鼠标离开框,项目就会被删除.但我希望用户能够改变主意.换句话说,如果他们意识到他们拖出错误的文件,我希望他们能够将鼠标移回 listBox
并释放鼠标以取消操作.我在想这意味着我需要能够捕获 MouseUp
事件而不是 DragLeave
事件.但这到目前为止还没有成功.
Right now, I have the removal of the item tied to the DragLeave
event, which means that as soon as the mouse leaves the box, the item is removed. But I'd like for users to be able to change their minds. In other words, if they realize they're dragging the wrong file out, I'd like them to be able to move the mouse back into the listBox
and release the mouse to cancel the action. I'm thinking that means I need to be able to capture the MouseUp
event instead of the DragLeave
event. But that hasn't been successful so far.
以下是我目前用于删除拖出文件的代码.如何修改以防止文件从列表中删除,直到用户放开鼠标按钮?
Below is the code I'm currently using for removing files dragged out. How can I modify to keep the files from being removed form the list until the user lets the mouse button go?
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
一样大.当有人将文件拖出列表时,他们将其完全拖出表单.我这样做是不是把自己逼到了墙角?我知道我正在让它变得比它必须的更难,但我仍然想看看如果可能的话它会如何工作.
The comments and answers so far have been useful, but I realize my question isn't clear enough. In this case, I'm displaying a dialog separate from the parent form that is basically as big as the listBox
. When someone drags a file out of the list, they're dragging it off the form completely. Have I backed myself into a corner by doing this? I recognize I'm making it harder than it has to be, but I'd still like to see how it would work if it's possible.
推荐答案
这里有一个相当快速的 hack 方法来获得你想要的功能:
Here's a fairly quick hack approach to gaining the functionality you want:
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;
}
每次用户将一个项目拖出框外时,它都会被临时保存,直到用户将其拖放到其他地方或将鼠标放在列表中的新项目上.请注意,其中重要的部分是检测用户何时何地松开鼠标,这是处理 Form1
的 DragDrop
事件的基本原理,Form1
的父级>listBox1.
Every time the user drags an item out of the box, it's saved temporarily until the user drops it somewhere else or mouses down on a new item in the list.
Note the important part of this is detecting when and where the user let's go of that mouse, which is the rationale behind handling the DragDrop
event of Form1
, the parent of listBox1
.
根据布局其余部分的复杂程度和密度,您处理 DragDrop
的位置可能会大不相同.这就是为什么它有点hacky"的原因,但它也很简单.不过,您将 lb_item
设为 null 的位置或次数并不重要,因为它只与特定的 ListBox
相关.
Depending on the sophistication and density of the rest of your layout, where you handle DragDrop
could be much different for you. This is why it's kind of "hacky", but it's also quite simple. It shouldn't matter, though, where or how many times you null lb_item
since it pertains only to that specific ListBox
.
我想另一种方法是跟踪用户的鼠标状态并采取相应的行动,如果处理大量 DragDrop
东西是不可想象的,这可能更适合你.
I suppose another way to do it would be to track the user's mouse states and act accordingly, which may be more appropriate for you if it's inconceivable to handle a lot of DragDrop
stuff.
如果您想要真正彻底,您可以使用 foreach
枚举基本表单的 每个 控件,并以编程方式将 DragDrop 事件的处理程序附加到该控件控制,然后在完成后将其删除......但这可能有点疯狂.我敢肯定有人有更好的方法.
If you wanted to be REAL thorough, you could enumerate through every control of the base form using foreach
and programmatically append a handler for the DragDrop event to that control, then remove it when done... but that may be getting a little nutty. I'm sure someone has a better approach.
这篇关于C# 从列表框中拖放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!