c# - studio - ¿Qué botón de opción del grupo está marcado?
radio button.net c# (11)
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;
}
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 etiquetas 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<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
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
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();
}
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<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 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).
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;
}
Puede conectar los CheckedEvents de todos los botones a un controlador. 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;
}
}
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 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 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;
Puedes usar LINQ:
var checkedButton = container.Controls.OfType<RadioButton>()
.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<RadioButton>
s en su constructor para cada grupo, luego escriba list.FirstOrDefault(r => r.Checked)
.
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 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.
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<RadioButton>()
.FirstOrDefault(r => r.Checked).Text;
File.WriteAllLines("Config.ini", lines);
luego llámalo con
string[] ini = File.ReadAllLines("Config.ini");
groupBoxTes.Controls.OfType<RadioButton>()
.FirstOrDefault(r => (r.Text == ini[0])).Checked = true;