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一样大。当某人从列表中拖出一个文件时,他们是将该文件完全拖出表单。我这样做是不是把自己逼到了死角?我知道我让事情变得更困难了,但如果可能的话,我还是想看看它是如何工作的。

c#从列表框中拖放

这里有一个相当快速的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的父节点Form1DragDrop事件的基本原理。

根据布局其余部分的复杂程度和密度,您处理DragDrop的位置可能会有很大不同。这就是为什么它有点"hacky",但它也很简单。但是,在哪里或多少次将lb_item为空并不重要,因为它只属于特定的ListBox

我想另一种方法是跟踪用户的鼠标状态并采取相应的行动,如果无法处理大量的DragDrop内容,这可能更适合您。

编辑:如果你想真正彻底,你可以枚举通过每个控件的基本形式使用foreach和编程附加一个处理程序的拖放事件到该控件,然后删除它完成后…但这可能有点疯狂。我肯定有人有更好的办法。