C# 我有一个“WinForms”;按钮";,如何在不激活按钮的情况下单击并拖动它?

C# 我有一个“WinForms”;按钮";,如何在不激活按钮的情况下单击并拖动它?,c#,winforms,C#,Winforms,我的WinForm只是一个40x40按钮,用户可以点击它来寻求帮助。除了单击并拖动按钮将其移动到屏幕的另一部分外,所有操作都正常。释放鼠标左键(完成“单击”)后,按钮将激活。在发生mousedown事件时,是否有方法检查窗口是否已移动,并在这种情况下停止mouseclick事件 我目前如何“点击并拖动”: 您可以使用一个标志来处理: private bool ignoreClick = false; private void btn_MouseMove(object sender, Mouse

我的WinForm只是一个40x40按钮,用户可以点击它来寻求帮助。除了单击并拖动按钮将其移动到屏幕的另一部分外,所有操作都正常。释放鼠标左键(完成“单击”)后,按钮将激活。在发生
mousedown
事件时,是否有方法检查窗口是否已移动,并在这种情况下停止
mouseclick
事件

我目前如何“点击并拖动”:


您可以使用一个标志来处理:

private bool ignoreClick = false;

private void btn_MouseMove(object sender, MouseEventArgs e) {
  if (e.Button == MouseButtons.Left) {
    ignoreClick = true;
    btn.Left = e.X + btn.Left - mouseDownLocation.X;
    btn.Top = e.Y + btn.Top - mouseDownLocation.Y;
  }
}

private void btn_MouseUp(object sender, MouseEventArgs e) {
  ignoreClick = false;
}

private void btn_Click(object sender, EventArgs e) {
  if (!ignoreClick) {
    // do your click code...
  }
}

如果可以使用子类按钮,则可以防止光标移动过远时触发单击事件(我认为这应该是默认行为)。
通过这种方式,实际的事件处理程序可以保持更干净,并且不必处理这个问题

class SpecialButton: Button
{
    private Point ClickOrigin;
    private const int ClickMaxDistance = 5;

    protected override void OnMouseDown(MouseEventArgs e)
    {
        ClickOrigin = System.Windows.Forms.Cursor.Position;
        base.OnMouseDown(e);
    }

    protected override void OnClick(EventArgs e)
    {
        Point p = System.Windows.Forms.Cursor.Position;
        if(Math.Abs(p.X - ClickOrigin.X) < ClickMaxDistance &&
            Math.Abs(p.Y - ClickOrigin.Y) < ClickMaxDistance)
        base.OnClick(e);
    }
}
class特殊按钮:按钮
{
专用点源;
私有常量int ClickMaxDistance=5;
MouseEventArgs e上的受保护覆盖无效(MouseEventArgs e)
{
单击原点=System.Windows.Forms.Cursor.Position;
base.OnMouseDown(e);
}
受保护的覆盖void OnClick(EventArgs e)
{
点p=System.Windows.Forms.Cursor.Position;
如果(Math.Abs(p.X-ClickOrigin.X)
您也可以通过如下按钮移动表单:

    public const int HT_CAPTION = 0x2;
    public const int WM_NCLBUTTONDOWN = 0xA1;

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool ReleaseCapture();
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Hello!");
    }

你是怎么做的?在标准窗体中拖动标准按钮不会导致窗体(或按钮)移动。我有什么遗漏吗?对不起,你没有遗漏任何东西。我将更新问题。现在,您的代码正在移动表单,而不是按钮。
    public const int HT_CAPTION = 0x2;
    public const int WM_NCLBUTTONDOWN = 0xA1;

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool ReleaseCapture();
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            ReleaseCapture();
            SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Hello!");
    }