为什么在OnClick之前调用Click,我该如何解决?

我有一个自定义button( public partial class QButton : Control )具有以下代码来更改自己的已检查状态,当用户单击它:

  protected override void OnMouseClick(MouseEventArgs e) { if (e.Button != System.Windows.Forms.MouseButtons.Left) { base.OnMouseClick(e); return; } Status tmp = m_status; if (m_status.HasFlag(Status.Checked)) m_status &= ~Status.Checked; else m_status |= Status.Checked; if (tmp != m_status) Invalidate(); base.OnMouseClick(e); } 

那部分工作正常。 在表单中使用这个button时,我将这样的事件连接起来:

  public void attach(Control.ControlCollection c) { /* ... */ m_Button.Click += OnEnable; } protected void OnEnable(object sender, EventArgs e) { /* the following still returns the old state as buttons OnMouseClick hasnt yet been called */ m_enabled = m_Button.Checked; updateEnableState(); } 

所以我想要的是我的表单被通知点击,并可以做一些魔术。 问题是表单我的button获取通知之前得到通知,所以首先调用窗体OnEnable方法,然后OnMouseClick方法被调用。

在表单涉及之前,如何通知button的成功点击事件?

Solutions Collecting From Web of "为什么在OnClick之前调用Click,我该如何解决?"

正如@PaulF指出的那样,问题在于实际上Click和MouseClick是不同的事件(不知道这一点),并且在MouseClick之前调用Click。

由于MouseClick仅在发生鼠标点击时被调用(并且可能引发doubleclicks问题),因此该按钮应该重写OnClick

所以解决办法是:

 protected override void OnClick(MouseEventArgs e) { Status tmp = m_status; if (m_status.HasFlag(Status.Checked)) m_status &= ~Status.Checked; else m_status |= Status.Checked; if (tmp != m_status) Invalidate(); base.OnClick(e); } 

…这也适用于键盘按钮上的点击。