2009-11-25 18 views
103

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)?¿Qué botón de opción del grupo está marcado?

 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

El código subyacente no sabe cuál de ellos para desmarcar, sólo se repite todos los controles RadioButton por debajo de la misma matriz del control cambiada y desactiva la anterior ya marcada. –

+1

¿Estás usando WinForms o ASP.Net? – SLaks

Respuesta

190

Se podría utilizar LINQ:

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

Tenga en cuenta que esto requiere que todos los botones de radio directamente en el mismo recipiente (por ejemplo, panel o forma), y que no es sólo un grupo en el contenedor. Si ese no es el caso, puede hacer List<RadioButton> s en su constructor para cada grupo, luego escriba list.FirstOrDefault(r => r.Checked).

+17

Tengo un libro de Linq ... ¡me acabas de convencer para que lo lean! – Billy

+1

Realmente debería leerlo; LINQ es una herramienta muy poderosa que se puede usar en aplicaciones que no tienen nada que ver con las bases de datos. – SLaks

+0

¿Debería ser 's.FirstOrDefault' en lugar de' list.FirstOrDefault' en el segundo párrafo de su respuesta? –

31

Puede conectar el CheckedEvents de todos los botones uno contra el manejador. Allí puede obtener fácilmente la casilla de verificación 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; 
    } 
} 
+0

Debería ser esto en su lugar - if (((RadioButton) remitente). Chequeado) –

+0

No hay CheckedChanged en RadioButton de WPF, ¿de dónde lo sacaste? –

5

Puede usar el evento CheckedChanged para todos sus RadioButtons. Sender serán los RadioButton sin marcar y verificados.

23

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

Se puede utilizar un método de extensión para recorrer la colección Parent.Controls de RadioButton. Esto le permite consultar otros RadioButtons en el mismo alcance. 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 Tag RadioButton puede ser usada para sostener una enumeración 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; 
+0

no está mal ... no está nada mal ... – naveen

9

El PO quería obtener RadioButton POR GRUPO comprobado. 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 el RadioButton comprobado de un grupo en particular:

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

Si su código tiene la posibilidad de no RadioButtons que se comprueba, a continuación, utilizar "SingleOrDefault()". (Si no estoy usando botones de tres estados, siempre configuro un botón "IsChecked" como una selección predeterminada).)

+1

r.GroupName == "GroupName" y r.IsChecked son de diferentes tipos (bool y bool?), deberías haber usado r.IsChecked.Value, que es de tipo bool. – Mike

+1

try '.Where (r => r.GroupName ==" GroupName "&& r.IsChecked == true)' porque 'r.IsChecked' es una propiedad bool que se puede nulos. – Firnas

+0

a qué se refiere myGrid aquí. – Unnikrishnan

0

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

string[] lines = new string[1]; 

lines[0] = groupBoxTes.Controls.OfType<RadioButton>() 
      .FirstOrDefault(r => r.Checked).Text; 

File.WriteAllLines("Config.ini", lines); 

luego llamar con

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

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

Uso de ejemplo:

int index = getCheckedRadioButton(panel1); 

El código no está bien probado, pero parece que el orden de los índices 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 intento 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.

0

Además del cableado CheckedChangedEvent uno puede utilizar los controles de "etiqueta" propiedad de distinguir entre los botones de radio ... un (espaguetis código) alternativa sería la propiedad "TabIndex"; P

+0

¿Qué significa todo esto? –

+0

significa que puede usar rápidamente la caja del conmutador en el ID del botón de radio seleccionado (usando la propiedad System.Windows.Forms.Control.Tag) , por favor, no califique si simplemente no entiende mi adición a la pregunta. –

1

A veces, en situaciones así 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 truco 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 opción con "Ninguno" y "NE", "SE", "NW" y "SW" como las etiquetas en los otros cuatro botones de radio.

Proactivamente utilicé un botón para capturar el valor del botón marcado, porque porque asignar un controlador de eventos a todos los eventos de botones CHeckCHanged 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<RadioButton> buttons = new List<RadioButton>(); 
     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

+0

Al modificar solo el resultado 'FormatableString', pude usar el código en mi programa. Tampoco estaba al tanto de radioButton Tag. Así es como deberían ser las respuestas. Gran señor – Unnikrishnan

Cuestiones relacionadas