C#从listBox拖放

时间:2013-05-16 15:46:28

标签: c# drag-and-drop event-handling

我正在尝试构建一个简单的界面,允许用户将文件拖放到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一样大。当有人将文件从列表中拖出时,他们会将文件完全拖离表单。这样做我是否支持自己进入角落?我知道我正在努力使它变得更难,但我仍然希望看到它如果有可能会如何运作。

1 个答案:

答案 0 :(得分:4)

这是获得所需功能的一种相当快速的黑客方法:

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;
}

每次用户将项目从框中拖出时,它都会暂时保存,直到用户将其放到其他位置或将鼠标放在列表中的新项目上。 请注意,这一点的重要部分是检测用户何时何地使用该鼠标,这是处理DragDrop的{​​{1}} Form1事件背后的基本原理。

根据布局其余部分的复杂程度和密度,您处理listBox1的位置可能会有所不同。这就是为什么它有点“hacky”,但它也很简单。但是,无论您将DragDrop置于何处或多少次都无关紧要,因为它仅与特定lb_item相关。

我认为另一种方法是跟踪用户的鼠标状态并采取相应的行动,如果处理大量ListBox事件是不可思议的,这可能更适合您。

编辑:如果你想真正彻底,你可以使用DragDrop通过基本表单的每个控件进行枚举,并以编程方式将DragDrop事件的处理程序附加到该控件,然后完成后删除它...但这可能会变得有点疯狂。我相信有人会有更好的方法。