【问题标题】:Detect whether multiple ListView items were selected by dragging检测是否通过拖拽选中了多个ListView项
【发布时间】:2016-01-26 12:40:50
【问题描述】:

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

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

在下面的示例中,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;
}

我知道这会很愚蠢。请让我摆脱痛苦。
或者,如果有人知道更好的方法是检测拖动选择(正确的术语是什么?),那么我全神贯注。

【问题讨论】:

  • 在 mouseup 中,获取 ListView1.SelectedItems 属性。释放鼠标后,在拖动过程中选择的任何项目都应在此属性中可用。
  • 这将包括在按住控制时通过单击选择的项目。我想要通过拖动特别选择的项目。
  • 听起来可能是个愚蠢的问题,但我还是要问:你确定listView1_MouseMove 方法实际上是分配给listview1MouseMove 事件处理程序的吗?看看InitializeComponent() 方法
  • 肯定是赋值的,触发了该处理程序内部设置的断点。亚历克斯,我已经更新了我的问题,使其更清晰,谢谢!
  • 你能钩listView1_PreviewMouseDownlistView1_PreviewMouseMove吗?可能只是事件在它冒泡到足以让 MouseDown 和 MouseMove 响应之前就被处理了。你的方法似乎是合理的,只要你能尽早挂钩事件。

标签: c# winforms listview


【解决方案1】:

你可以试试这个:

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

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

【讨论】:

  • 虽然我已经尝试了这两种方法,但不幸的是它们都不起作用,但你确实让我的大脑运转并引导我解决了这个问题,所以请给我的朋友点个赞。
【解决方案2】:

经过进一步调查,我发现对于 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!
    }
}

【讨论】:

    猜你喜欢
    • 2011-04-07
    • 2011-10-21
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 2020-10-16
    • 1970-01-01
    相关资源
    最近更新 更多