¿Qué botón de opción del grupo está marcado?

Usando WinForms; ¿Hay una mejor manera de encontrar el RadioButton verificado para un grupo? Me parece que el código a continuación no debería ser necesario. Cuando comprueba un RadioButton diferente, entonces sabe cuál desactivar, por lo que debe saber cuál es verificado. ¿Cómo obtengo esa información sin hacer muchas declaraciones if (o un cambio)?

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

Puedes usar LINQ:

 var checkedButton = container.Controls.OfType() .FirstOrDefault(r => r.Checked); 

Tenga en cuenta que esto requiere que todos los botones de radio estén directamente en el mismo contenedor (por ejemplo, Panel o Formulario), y que solo haya un grupo en el contenedor. Si ese no es el caso, puede hacer que List s en su constructor para cada grupo, luego escriba list.FirstOrDefault(r => r.Checked) .

Puede conectar los CheckedEvents de todos los botones a un controlador. Allí puede obtener fácilmente la checkbox correcta.

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

Para aquellos sin 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; } 

El OP quería obtener el RadioButton verificado POR GRUPO. Si bien la respuesta de @SLaks es excelente, en realidad no responde la pregunta principal de OP. Para mejorar la respuesta de @SLaks, simplemente lleve el LINQ un paso más allá.

Aquí hay un ejemplo de mi propio código de trabajo. Por WPF normal, mis RadioButtons están contenidos en una grilla (llamada “myGrid”) con muchos otros tipos de controles. Tengo dos grupos diferentes de RadioButton en la Grilla.

Para obtener RadioButton verificado de un grupo en particular:

 List buttons = myGrid.Children.OfType().ToList(); RadioButton rbTarget = radioButtons .Where(r => r.GroupName == "GroupName" && r.IsChecked) .Single(); 

Si su código tiene la posibilidad de que no se verifiquen RadioButtons, entonces use “SingleOrDefault ()”. (Si no estoy usando botones de tres estados, siempre configuro un botón “IsChecked” como una selección predeterminada).

Puede usar el evento CheckedChanged para todos sus RadioButtons. Sender será RadioButtons sin marcar y verificado.

Puede usar un método de extensión para iterar la colección Parent.Controls de RadioButton. Esto le permite consultar otros RadioButtons en el mismo scope. Usando dos métodos de extensión, puede usar primero para determinar si se seleccionan los RadioButtons en el grupo, luego use el segundo para obtener la selección. El campo RadioButton Tag se puede usar para contener un Enum para identificar cada RadioButton en el grupo:

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

Aquí hay un patrón de uso típico:

 if(!MyRadioButton.IsRadioSelected()) { MessageBox.Show("No radio selected."); return; } int selection = MyRadioButton.GetRadioSelection; 

A veces, en situaciones como esta, echo de menos mi juventud, cuando Access era mi veneno de elección, y podía darle a cada botón de radio de un grupo su propio valor.

Mi hack en C # es usar la etiqueta para establecer el valor, y cuando hago una selección del grupo, leo el valor de la etiqueta del botón de radio seleccionado. En este ejemplo, directionGroup es el grupo en el que tengo cuatro cinco botones de radio con “Ninguno” y “NE”, “SE”, “NW” y “SW” como las tags en los otros cuatro botones de radio.

Proactivamente usé un botón para capturar el valor del botón marcado, porque porque asignar un controlador de eventos a todos los eventos CHEckCHanged de los botones hace que CADA botón se dispare, porque cambiar uno los cambia a todos. Entonces, el valor del emisor es siempre el primer RadioButton en el grupo. En cambio, utilizo este método cuando necesito saber cuál se selecciona, con los valores que deseo recuperar en la propiedad Etiqueta de cada 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, lo he probado y lo he usado en mi trabajo.

Joey

si desea guardar la selección en un archivo o en cualquier otro y llamarlo más tarde, aquí lo que hago

 string[] lines = new string[1]; lines[0] = groupBoxTes.Controls.OfType() .FirstOrDefault(r => r.Checked).Text; File.WriteAllLines("Config.ini", lines); 

luego llámalo con

 string[] ini = File.ReadAllLines("Config.ini"); groupBoxTes.Controls.OfType() .FirstOrDefault(r => (r.Text == ini[0])).Checked = true; 

Además del cableado CheckedChangedEvent, se podría usar la propiedad “Tag” de los controles para distinguir entre los botones de radio … una alternativa (código de espaghetti) sería la propiedad “TabIndex”; P

Si desea obtener el índice del botón de opción seleccionado dentro de un control, puede usar este método:

 public static int getCheckedRadioButton(Control c) { int i; try { Control.ControlCollection cc = c.Controls; for (i = 0; i < cc.Count; i++) { RadioButton rb = cc[i] as RadioButton; if (rb.Checked) { return i; } } } catch { i = -1; } return i; } 

Ejemplo de uso:

 int index = getCheckedRadioButton(panel1); 

El código no está bien probado, pero parece que el orden del índice es de izquierda a derecha y de arriba a abajo, como cuando se lee un texto. Si no se encuentra un botón de opción, el método devuelve -1.

Actualización: Resultó que mi primer bash no funcionó si no había un botón de opción dentro del control. Agregué un bloque try y catch para arreglar eso, y el método ahora parece funcionar.

El GroupBox tiene un evento Validado para este propósito, si está utilizando 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(); }