可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Using WinForms; Is there a better way to find the checked RadioButton for a group? It seems to me that the code below should not be necessary. When you check a different RadioButton then it knows which one to uncheck… so it should know which is checked. How do I pull that information without doing a lot of if statements (or a switch).
RadioButton rb = null; if (m_RadioButton1.Checked == true) { rb = m_RadioButton1; } else if (m_RadioButton2.Checked == true) { rb = m_RadioButton2; } else if (m_RadioButton3.Checked == true) { rb = m_RadioButton3; }
回答1:
You could use LINQ:
var checkedButton = container.Controls.OfType() .FirstOrDefault(r => r.Checked);
Note that this requires that all of the radio buttons be directly in the same container (eg, Panel or Form), and that there is only one group in the container. If that is not the case, you could make List
s in your constructor for each group, then write list.FirstOrDefault(r => r.Checked)
.
回答2:
You can wire the CheckedEvents of all the buttons against one handler. There you can easily get the correct Checkbox.
// Wire all events into this. private void AllCheckBoxes_CheckedChanged(Object sender, EventArgs e) { // Check of the raiser of the event is a checked Checkbox. // Of course we also need to to cast it first. if (((RadioButton)sender).Checked) { // This is the correct control. RadioButton rb = (RadioButton)sender; } }
回答3:
For those without LINQ:
RadioButton GetCheckedRadio(Control container) { foreach (var control in container.Controls) { RadioButton radio = control as RadioButton; if (radio != null && radio.Checked) { return radio; } } return null; }
回答4:
The OP wanted to get the checked RadioButton BY GROUP. While @SLaks' answer is excellent, it doesn't really answer the OP's main question. To improve on @SLaks' answer, just take the LINQ one step further.
Here's an example from my own working code. Per normal WPF, my RadioButtons are contained in a grid (named "myGrid") with a bunch of other types of controls. I have two different RadioButton groups in the Grid.
To get the checked RadioButton from a particular group:
List buttons = myGrid.Children.OfType().ToList(); RadioButton rbTarget = radioButtons .Where(r => r.GroupName == "GroupName" && r.IsChecked) .Single();
If your code has the possibility of no RadioButtons being checked, then use "SingleOrDefault()." (If I'm not using tri-state buttons, then I always set one button "IsChecked" as a default selection.)
回答5:
You can use the CheckedChanged event for all your RadioButtons. Sender
will be the unchecked and checked RadioButtons.
回答6:
You can use an Extension method to iterate the RadioButton's Parent.Controls collection. This allows you to query other RadioButtons in the same scope. Using two extension methods, you can use the first determine whether any RadioButtons in the group are selected, then use the second to get the selection. The RadioButton Tag field can be used to hold an Enum to identify each RadioButton in the group:
public static int GetRadioSelection(this RadioButton rb, int Default = -1) { foreach(Control c in rb.Parent.Controls) { RadioButton r = c as RadioButton; if(r != null && r.Checked) return Int32.Parse((string)r.Tag); } return Default; } public static bool IsRadioSelected(this RadioButton rb) { foreach(Control c in rb.Parent.Controls) { RadioButton r = c as RadioButton; if(r != null && r.Checked) return true; } return false; }
Here's a typical use pattern:
if(!MyRadioButton.IsRadioSelected()) { MessageBox.Show("No radio selected."); return; } int selection = MyRadioButton.GetRadioSelection;
回答7:
Sometimes in situations like this I miss my youth, when Access was my poison of choice, and I could give each radio button in a group its own value.
My hack in C# is to use the tag to set the value, and when I make a selection from the group, I read the value of the tag of the selected radiobutton. In this example, directionGroup is the group in which I have four five radio buttons with "None" and "NE", "SE", "NW" and "SW" as the tags on the other four radiobuttons.
I proactively used a button to capture the value of the checked button, because because assigning one event handler to all of the buttons' CHeckCHanged event causes EACH button to fire, because changing one changes them all. So the value of sender is always the first RadioButton in the group. Instead, I use this method when I need to find out which one is selected, with the values I want to retrieve in the Tag property of each RadioButton.
private void ShowSelectedRadioButton() { List buttons = new List(); string selectedTag = "No selection"; foreach (Control c in directionGroup.Controls) { if (c.GetType() == typeof(RadioButton)) { buttons.Add((RadioButton)c); } } var selectedRb = (from rb in buttons where rb.Checked == true select rb).FirstOrDefault(); if (selectedRb!=null) { selectedTag = selectedRb.Tag.ToString(); } FormattableString result = $"Selected Radio button tag ={selectedTag}"; MessageBox.Show(result.ToString()); }
FYI, I have tested and used this in my work.
Joey
回答8:
if you want to save the selection to file or any else and call it later, here what I do
string[] lines = new string[1]; lines[0] = groupBoxTes.Controls.OfType() .FirstOrDefault(r => r.Checked).Text; File.WriteAllLines("Config.ini", lines);
then call it with
string[] ini = File.ReadAllLines("Config.ini"); groupBoxTes.Controls.OfType() .FirstOrDefault(r => (r.Text == ini[0])).Checked = true;
回答9:
In addition to the CheckedChangedEvent wiring one could use the Controls "Tag" property to distinguish between the radio buttons... an (spaghetti code) alternative would be the "TabIndex" property ;P
回答10:
If you want to get the index of the selected radio button inside a control you can use this method:
public static int getCheckedRadioButton(Control c) { int i; try { Control.ControlCollection cc = c.Controls; for (i = 0; i
Example use:
int index = getCheckedRadioButton(panel1);
The code isn't that well tested, but it seems the index order is from left to right and from top to bottom, as when reading a text. If no radio button is found, the method returns -1.
Update: It turned out my first attempt didn't work if there's no radio button inside the control. I added a try and catch block to fix that, and the method now seems to work.
回答11:
The GroupBox has a Validated event for this purpose, if you are using WinForms.
private void grpBox_Validated(object sender, EventArgs e) { GroupBox g = sender as GroupBox; var a = from RadioButton r in g.Controls where r.Checked == true select r.Name; strChecked = a.First(); }