C# 从列表框中拖放

tmo*_*e82 4 c# drag-and-drop event-handling

我正在尝试构建一个简单的界面,该界面允许用户将文件放入 alistBox以将它们添加到进程中,并将它们拖出以将其删除。一切正常,但我想添加一个功能,让它更复杂一点。

现在,我删除了与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);
}
Run Code Online (Sandbox Code Playgroud)

编辑 2013/05/16

到目前为止的评论和答案很有用,但我意识到我的问题还不够清楚。在这种情况下,我将显示一个与父表单分开的对话框,该对话框基本上与listBox. 当有人将文件拖出列表时,他们将其完全拖出表单。我这样做是否让自己陷入困境?我承认我让它变得比它更难,但如果可能的话,我仍然想看看它是如何工作的。

B L*_*B L 5

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

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;
}
Run Code Online (Sandbox Code Playgroud)

每次用户将项目拖出框时,它都会暂时保存,直到用户将其放在其他地方或将鼠标放在列表中的新项目上。请注意,其中重要的部分是检测用户何时何地放开鼠标,这是处理 的DragDrop事件的基本原理Form1, 的父级listBox1

根据布局其余部分的复杂程度和密度,您处理的位置对您来说DragDrop可能大不相同。这就是为什么它有点“hacky”,但它也很简单。但是,您在何处或多少次 null 应该无关紧要,lb_item因为它仅与特定的ListBox.

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

编辑:如果你想真正彻底,你可以枚举基本表单的每个控件,foreach并以编程方式将 DragDrop 事件的处理程序附加到该控件,然后在完成后将其删除......但这可能有点疯狂. 我敢肯定有人有更好的方法。