Question

I'd like to be able to catch the DoubleClick or MouseDoubleClick events from a standard winforms radio button, but they seem to be hidden and not working. At the moment I have code like this:

public class RadioButtonWithDoubleClick : RadioButton
{
    public RadioButtonWithDoubleClick()
        : base()
    {
        this.SetStyle( ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true );
    }

    [EditorBrowsable( EditorBrowsableState.Always ), Browsable( true )]
    public new event MouseEventHandler MouseDoubleClick;
    protected override void OnMouseDoubleClick( MouseEventArgs e )
    {
        MouseEventHandler temp = MouseDoubleClick;
        if( temp != null ) {
            temp( this, e );
        }
    }
}

Is there a simpler and cleaner way to do it?

Edit: For background, I agree with Raymond Chen's post here that the ability to double click on a radio button (if those are the only controls on the dialog) makes the dialog just a tiny bit easier to use for people who know about it.

In Vista using Task Dialogs (see this Microsoft guideline page or this MSDN page specifically about the Task Dialog API) would be the obvious solution, but we don't have the luxury of that.

Was it helpful?

Solution

Based on your original suggestion I made a solution without the need to subclass the radiobuton using reflection:

MethodInfo m = typeof(RadioButton).GetMethod("SetStyle", BindingFlags.Instance | BindingFlags.NonPublic);
if (m != null)
{
    m.Invoke(radioButton1, new object[] { ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true });
}
radioButton1.MouseDoubleClick += radioButton1_MouseDoubleClick;

Now the double click event for the radiobutton is fired. BTW: The suggestion of Nate using e.Clicks doesn't work. In my tests e.Clicks was always 1 no matter how fast or often I clicked the radiobutton.

OTHER TIPS

You could do something like this:

myRadioButton.MouseClick += new MouseEventHandler(myRadioButton_MouseClick);

void myRadioButton_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Clicks == 2)
    {
         // Do something
    }
}

You may or may not also want to check that e.Button == MouseButtons.Left

Based on @MSW answer, I made this extension class:

static class RadioButtonEx
{
    public static void AllowDoubleClick(this RadioButton rb, MouseEventHandler MouseDoubleClick)
    {
        //
        // Allow double clicking of radios
        System.Reflection.MethodInfo m = typeof(RadioButton).GetMethod("SetStyle", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        if (m != null)
            m.Invoke(rb, new object[] { ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true });

        rb.MouseDoubleClick += MouseDoubleClick;
    }
}

Which is then super easy to set up and re-use:

radioButton.AllowDoubleClick((a, b) => myDoubleClickAction());

Sorry, don't have the reputation to comment on this. What action are you trying to have the double-click perform for the user? I think using a double-click may be confusing because it is different from the general mental model that a user has of a radio-button (IE single click, select one option from a set)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top