检测是否通过拖动选择了多个ListView项目

时间:2016-01-26 12:40:51

标签: c# winforms listview

我有一个ListView,View设置为LargeIcon 我特别需要通过用鼠标拖动选择框来检测何时选择了多个项目。 (例如,我不想知道CTRL + Click选择项目的时间)

我想我可以通过跟踪鼠标在移动时是否向下移动来表示拖动,然后在鼠标向上移动(如果它是拖动)然后我可以设置另一个变量来指示这一点。

在下面的示例中,mouseDown设置为true,但是当我将鼠标按下并移动它时,isDrag永远不会设置为true,我无法看到我的内容。做错了。
(编辑:isDrag如果我删除了if这个奇怪的子句就变成了,因为我说mouseDown肯定是真的。)

我意识到代码需要的时间比它需要的长一些,但为了清晰起见。

bool mouseDown;
bool isDrag;
bool wasDrag;

private void listView1_MouseDown(object sender, MouseEventArgs args)
{
    wasDrag = false;
    mouseDown = true;
}

private void listView1_MouseMove(object sender, MouseEventArgs args)
{
    if (mouseDown)
        isDrag = true; // <-- Never becomes true, even though mouseDown is true
}

private void listView1_MouseUp(object sender, MouseEventArgs args)
{
    if (isDrag)
        wasDrag = true;

    mouseDown = false;
    isDrag = false;
}

我知道它会变得愚蠢。请把我从痛苦中解脱出来 或者,如果有人知道更好的方法是检测拖动选择(适当的术语是什么?)那么我就是所有的耳朵。

2 个答案:

答案 0 :(得分:1)

你可以试试这个:

private void listView1_MouseMove(object sender, MouseEventArgs args)
{
    isDrag = mouseDown;
}

我认为由于某种原因,您的事件 listView1_MouseUp 仍然会触发,这会使您的isDrag变量设置为非预期值。尝试在 MouseMove MouseUp 事件上设置断点,以查看它们触发的顺序。

答案 1 :(得分:0)

经过进一步调查后,我发现对于ListView控件,当MouseDown仍在发生时,MouseMove事件不会触发,并在释放鼠标后立即触发。 我只能假设此控件中内置的逻辑允许您通过拖动选择来选择多个文件,这些事件正在搞乱这些事件,并且基本上使它们同步。

我为此制定了一个基本的解决方法。这不是理想的,但它完成了工作,所以我想我会分享。

基本上当鼠标宕机时我会记录位置。当鼠标上升时,我检查它是否在任何方向上移动了一定距离。如果它没有我认为它是一个点击,如果它有我认为它是一个拖累。

// Records the mouse position on mousedown
int beforeMoveX;
int beforeMoveY;

// How far in pixels the mouse must move in any direction
// before we consider this a drag rather than a click
int moveBounds = 20;

private void listView1_MouseDown(object sender, MouseEventArgs e)
{
    // Save the mouse position
    beforeMoveX = e.X;
    beforeMoveY= e.Y;
}

private void listView1_MouseUp(object sender, MouseEventArgs e)
{
    // Did we move more than the bounds in any direction?
    if (e.X < (beforeMoveX - moveBounds) || 
        e.X > (beforeMoveX + moveBounds) || 
        e.Y < (beforeMoveY - moveBounds) || 
        e.Y > (beforeMoveY + moveBounds))
    {
        // DRAGGED!
    }
    else
    {
        // NOT DRAGGED!
    }
}