vb.net 为什么在同一元素上的 mouseDown 事件触发后不触发双击事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14731304/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 12:13:56  来源:igfitidea点击:

Why doesn't doubleclick event fire after mouseDown event on same element fires?

.netvb.net

提问by ashish_pal

I have a mousedown event and click event on a control. the mousedown event is used for starting dragdrop operation. The control I am using is a Dirlistbox.

我在控件上有一个 mousedown 事件和 click 事件。mousedown 事件用于开始拖放操作。我使用的控件是 Dirlistbox。

 Private Sub Dir1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Dir1.MouseDown

    Dim lab As New Label
    lab.Text = Dir1.DirList(Dir1.DirListIndex)
    lab.DoDragDrop(lab, DragDropEffects.Copy)

End Sub

But when i click on the control then only the mousedown event fires, click event does not get fire. If I comment out "lab.DoDragDrop(lab, DragDropEffects.Copy)" in the mousedown event then click event gets fire. what can I do so that both mousedown and click event gets fire when i click on the control?

但是当我点击控件时,只有 mousedown 事件触发,click 事件不会触发。如果我在 mousedown 事件中注释掉“lab.DoDragDrop(lab, DragDropEffects.Copy)”,则单击事件会触发。我该怎么做才能在单击控件时同时触发 mousedown 和 click 事件?

回答by Hans Passant

This is by design. The MouseDown event captures the mouse, Control.Capture property. The built-in MouseUp event handler checks if the mouse is still captured and the mouse hasn't moved too far, then fires the Click event. Trouble is that calling DoDragDrop() will cancel mouse capture. Necessarily so since mouse events are now used to implement the drag+drop operation. So you'll never get the Click nor the DoubleClick event.

这是设计使然。MouseDown 事件捕获鼠标,Control.Capture 属性。内置的 MouseUp 事件处理程序检查鼠标是否仍然被捕获并且鼠标没有移动太远,然后触发 Click 事件。问题是调用 DoDragDrop() 会取消鼠标捕获。必须如此,因为现在使用鼠标事件来实现拖放操作。所以你永远不会得到 Click 或 DoubleClick 事件。

Controls that both need to respond to clicks anddrag+drop are a usability problem. It is fixable however, what you need to do is ensure that the user has moved the mouse enough from the original mouse down location, thenstart the drag. Make your code look like this:

需要响应点击拖放的控件是一个可用性问题。但是,它是可修复的,您需要做的是确保用户已将鼠标从原始鼠标向下位置移动到足够的位置,然后开始拖动。让你的代码看起来像这样:

Private MouseDownPos As Point

Private Sub Dir1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Dir1.MouseDown
    MouseDownPos = e.Location
End Sub

Private Sub Dir1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Dir1.MouseMove
    If e.Button And MouseButtons.Left = MouseButtons.Left Then
        Dim dx = e.X - MouseDownPos.X
        Dim dy = e.Y - MouseDownPos.Y
        If Math.Abs(dx) >= SystemInformation.DoubleClickSize.Width OrElse _
           Math.Abs(dy) >= SystemInformation.DoubleClickSize.Height Then
            '' Start the drag here
            ''...
        End If
    End If
End Sub

回答by Ozkan Konca

for who needs c# version with drag and drop

谁需要带有拖放功能的 c# 版本

    private Point MouseDownPos;
    private void dataGridView1_MouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
    {
        MouseDownPos = e.Location;
    }

    private void dataGridView1_MouseMove(System.Object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            dynamic dx = e.X - MouseDownPos.X;
            dynamic dy = e.Y - MouseDownPos.Y;
            if (Math.Abs(dx) >= SystemInformation.DoubleClickSize.Width || Math.Abs(dy) >= SystemInformation.DoubleClickSize.Height)
            {
                DataGridView.HitTestInfo info = dataGridView1.HitTest(e.X, e.Y);
                if (info.RowIndex >= 0)
                {
                    DataRowView view = (DataRowView)
                           dataGridView1.Rows[info.RowIndex].DataBoundItem;

                    if (view != null)
                        dataGridView1.DoDragDrop(view, DragDropEffects.Move);

                }
            }
        }
    }