1

I have a custom button (public partial class QButton : Control) that has the following code to change its own checked-state when a user clicks on it:

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

That part is working well. When using this button in a form, I connect the events in the form like this:

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

So what I want is that my form gets notified of the click and can do some magic. The problem is that the form gets notified before my button gets the notification, so first the forms OnEnable-method gets called and then the Buttons OnMouseClick-method gets called.

How do I notify the button of a sucessfull click-event before the form gets involved?

rhavin
  • 1,512
  • 1
  • 12
  • 33
  • 1
    See first answer here as to order of events : http://stackoverflow.com/questions/21670126/click-doubleclick-vs-mouseclick-and-mousedoubleclick-events I am not sure what you mean by "the forms OnEnable method gets called" first - you have attached the OnEnable method to the buttons Click event - so it is the buttons click event that fires first - as described in the link. – PaulF Mar 14 '17 at 12:46

1 Answers1

1

As @PaulF pointed out, the problem was that in fact Click and MouseClick are different events (didnt knew that) and that Click gets called before MouseClick.

As MouseClick only gets called on an occuring mouseclick (and might raise problems with doubleclicks), the button should override OnClick

So the solution is:

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

…which also works for keyboard issued clicks on the button.

rhavin
  • 1,512
  • 1
  • 12
  • 33
  • Main difference is that click will work whatever clicked the button (smartphone, mouse, keyboard or any device that can perform such an action...) while MouseClick is fired only, well, when the mouse is clicked... – Martin Verjans Mar 14 '17 at 13:12