Grouping Windows Forms Radiobuttons with different parent controls in C#
Asked Answered
A

4

11

I've got a Windows Forms application in which I have a number of RadioButtons. These RadioButtons are placed within a FlowLayoutPanel which automatically arranges them for me. All RadioButtons that are directly added to the FlowLayoutPanel are grouped, meaning I can select only one of them. However, some of these RadioButtons are paired up with a TextBox so I can supply some argument there. But to have all this arranged properly, I add a Panel control to the FlowLayoutPanel so I can control the alignment of the RadioButton and TextBox relatively to each other myself.

These RadioButtons now have their own respective Panels as parent controls and thus are no longer included in the radio group with the other RadioButtons. I read that the the RadioButtons that are in the System.Web.UI namespace have a GroupName property, but unfortunately their System.Windows.Forms counterparts lack this property. Is there some other way I can group these radio buttons are am I going to have to handle onClick events myself?

Thanks, Jerry

Attica answered 7/1, 2011 at 15:47 Comment(1)
Normally we will use group box to group the radio buttons..Sedimentary
U
13

I'm afraid you'll have to handle this manually... It's not so bad actually, you can probably just store all the RadioButton in a list, and use a single event handler for all of them:

private List<RadioButton> _radioButtonGroup = new List<RadioButton>();
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
    RadioButton rb = (RadioButton)sender;
    if (rb.Checked)
    {
        foreach(RadioButton other in _radioButtonGroup)
        {
            if (other == rb)
            {
                continue;
            }
            other.Checked = false;
        }
    }
}
Uriel answered 7/1, 2011 at 20:37 Comment(3)
I was afraid this would be the case. Shouldn't be a problem though. Thanks for the help.Attica
fix : rb.Checked = false; => other.Checked = false;Embryogeny
@maxirby, I don't understand your comment... what do you mean?Uriel
N
2

I agree with @JonH - using tags is the cleanest way to do that (imho)

  private void FormLoad(object sender, EventArgs e)
  {
     radioCsv.Tag = DataTargetTypes.CsvFile;
     radioTabbed.Tag = DataTargetTypes.TxtFile;
     radioSas.Tag = DataTargetTypes.SasFile;
  }

  private void RadioButtonCheckedChanged(object sender, EventArgs e)
  {
     var radio = (RadioButton) sender;
     this.DataDestinationType = (DataTargetTypes)radio.Tag;
  }
Nebo answered 4/4, 2012 at 12:5 Comment(0)
R
0

@Jerry, I'm not too familiar with Windows Forms, but I will take a shot. If there a property called Tag, you could tag each radio button with a unique tag.

Relativize answered 7/1, 2011 at 15:51 Comment(0)
B
0

Here is a little improvement over the first answer: create a RadioGroup class that encapsulates the grouping functionality and adds support for standard keyboard navigation (up/down keys) and makes tabbing work.

To use it, simply declare a RadioGroup member in your form and new it (after InitializeComponent()), passing all the radio buttons you want in the group in proper order.

public class RadioGroup
{
    List<RadioButton> _radioButtons;

    public RadioGroup(params RadioButton[] radioButtons)
    {
        _radioButtons = new List<RadioButton>(radioButtons);
        foreach (RadioButton radioButton in _radioButtons)
        {
            radioButton.TabStop = false;
            radioButton.KeyUp += new KeyEventHandler(radioButton_KeyUp);
            radioButton.CheckedChanged += new EventHandler(radioButton_CheckedChanged);
        }
        _radioButtons[0].TabStop = true;
    }

    void radioButton_KeyUp(object sender, KeyEventArgs e)
    {
        e.Handled = true;
        RadioButton radioButton = (RadioButton)sender;
        int index = _radioButtons.IndexOf(radioButton);

        if (e.KeyCode == Keys.Down)
        {
            index++;
            if (index >= _radioButtons.Count)
            {
                index = 0;
            }
            e.Handled = true;
        }
        else if (e.KeyCode == Keys.Up)
        {
            index--;
            if (index < 0)
            {
                index = _radioButtons.Count - 1;
            }
            e.Handled = true;
        }

        radioButton = _radioButtons[index];
        radioButton.Focus();
        radioButton.Select();
    }

    void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        RadioButton currentRadioButton = (RadioButton)sender;

        if (currentRadioButton.Checked)
        {
            foreach (RadioButton radioButton in _radioButtons)
            {
                if (!radioButton.Equals(currentRadioButton))
                {
                    radioButton.Checked = false;
                }
            }
        }
    }
}

One caveat: the up/down keys won't work well with the existing RadioButton class because it already handles the up/down keys. One easy way to fix it to subclass RadioButton and turn off handling of up/down keys:

public class RadioButtonEx : RadioButton
{
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == Keys.Up || keyData == Keys.Down)
        {
            return true;
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }
}
Bluhm answered 18/4, 2012 at 22:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.