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

时间:2017-03-14 12:33:32

标签: c# windows events

我有一个自定义按钮(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);
    }

那部分运作良好。在表单中使用此按钮时,我将以如下形式连接事件:

    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();
    }

所以我想要的是我的表单会收到点击通知,可以做一些魔术。问题是在我的按钮获取通知之前表单会被通知,因此首先调用表单OnEnable - 方法,然后调用Buttons OnMouseClick - 方法。< / p>

如何在表单介入之前通知按钮成功点击事件?

1 个答案:

答案 0 :(得分:1)

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

由于MouseClick仅在发生鼠标点击时被调用(并且可能引发双击问题),该按钮应覆盖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);
}

...这也适用于键盘发出的点击按钮。