【问题标题】:in winforms, how can i make a control not accept mouse events在winforms中,如何使控件不接受鼠标事件
【发布时间】:2014-08-01 23:46:59
【问题描述】:

我有一个按钮,当 mouseenter 时,会弹出一个小表单,当鼠标离开按钮时,这个小表单会消失。我需要这种形式不接受任何鼠标事件,换句话说,对鼠标是“不可见的”。

问题是,窗体在鼠标下弹出,触发了按钮的 mouseleave 事件。我知道还有其他方法可以解决这个问题,但是当鼠标离开触发表单的原始按钮时,我需要隐藏表单,并且我还需要表单出现在鼠标下方。

那么我怎样才能让这个小弹出窗体对鼠标事件不可见,这样它就不会导致“鼠标离开”事件触发按钮?

弹出窗口的类型为“表单”。这是触发显示和隐藏表单的 mouseEnter 和 mouseLeave 代码:

private void btnPatientSearch_MouseEnter(object sender, EventArgs e)
        {
                _currentPatientInfo = new PatientInfo()
                {
                    MdiParent = this.MdiParent
                };
                _currentPatientInfo.Show();
                _currentPatientInfo.Location = new Point(181, 9);
            }
        }

        private void btnPatientSearch_MouseLeave(object sender, EventArgs e)
        {
            if (_currentPatientInfo == null) return;
            _currentPatientInfo.Hide();
            _currentPatientInfo = null;
        }

【问题讨论】:

  • 弹出窗口是不可见的还是在指针处绘制的?当您查看 form1.designer.cs 时,它在哪里绘制了框。或者更好的是,您可以修改帖子并为弹出窗口添加自动生成的代码吗?还有它是什么?是面板吗?你也可以发布按钮的鼠标事件吗?
  • 好的,我添加了 mouseenter 和 mouseleave 代码。设计师生成的代码不少。
  • 添加 btnPatientSearch.Capture = true;在 MouseEnter 事件处理程序中。
  • 专注于创建一个可用的用户界面。您所做的一切都没有任何意义,您当然要确保此表单永远不会与按钮重叠。这听起来也很强烈,这需要成为一个工具提示。

标签: c# winforms


【解决方案1】:

从以下表单类继承您的弹出表单。此代码正在使用一些 p/invokes 并且未经测试,但它应该可以工作。

public class PopupForm : Form
{
  private const int WS_BORDER = 0x00800000;
  private const int WS_POPUP = unchecked((int)0x80000000);

  private const int WS_EX_TOPMOST = 0x00000008;
  private const int WS_EX_NOACTIVATE = 0x08000000;

  private const int WM_MOUSEACTIVATE = 0x0021;
  private const int MA_NOACTIVATEANDEAT = 4;

  private static readonly IntPtr HWND_TOPMOST = (IntPtr)(-1);

  private const int SWP_NOSIZE = 0x0001;
  private const int SWP_NOMOVE = 0x0002;
  private const int SWP_NOACTIVATE = 0x0010;

  [DllImport("user32.dll")]
  [return: MarshalAs(UnmanagedType.Bool)]
  private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
    int X, int Y, int cx, int cy, int uFlags);

  public PopupForm()
  {
    SetStyle(ControlStyles.Selectable, false);
    FormBorderStyle = FormBorderStyle.None;
    StartPosition = FormStartPosition.Manual;
    ShowInTaskbar = false;
    Visible = false;
  }

  protected override CreateParams CreateParams
  {
    get
    {
      CreateParams cp = base.CreateParams;
      cp.Style |= WS_POPUP | WS_BORDER;
      cp.ExStyle |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
      return cp;
    }
  }

  protected override bool ShowWithoutActivation
  {
    get { return true; }
  }

  protected override void WndProc(ref Message m)
  {
    if (m.Msg == WM_MOUSEACTIVATE)
    {
      OnClick(EventArgs.Empty);
      m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
    }
    else
      base.WndProc(ref m);
  }

  public new void Show()
  {
    Windows.SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
      SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
    base.Show();
  }
}

【讨论】:

    猜你喜欢
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 1970-01-01
    • 2021-11-29
    • 2010-10-18
    相关资源
    最近更新 更多