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