检测是否通过拖动选择了多个列表视图项

本文关键字:列表 视图 选择 是否 拖动 检测 | 更新日期: 2023-09-27 18:32:00

我有一个列表视图,视图设置为LargeIcon。
我特别需要通过使用鼠标在它们周围拖动选择框来检测何时选择了多个项目。(例如,我不想知道何时通过 CTRL + 单击选择项目)

我认为我可以通过跟踪鼠标在移动时是否向下来简单地做到这一点,这将指示拖动,然后在鼠标向上时,如果是拖动,那么我可以设置另一个变量来指示这一点。

在下面的示例中,mouseDown设置为 true,但是当我按住鼠标并移动它时isDrag永远不会设置为 true,我看不到我做错了什么。
(编辑:如果我删除if子句,isDrag变得很奇怪,因为正如我所说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;
}

我知道这会是一件愚蠢的事情。请把我从痛苦中解救出来。
或者,如果有人知道更好的是检测拖动选择(正确的术语是什么?),那么我全都听着。

检测是否通过拖动选择了多个列表视图项

你能试试这个吗:

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

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

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

我已经为此整理了一个基本的解决方法。这并不理想,但它可以完成工作,所以我想我会分享。

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

// 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!
    }
}