Quel bouton radio du groupe est coché?


118

Utilisation de WinForms; Existe-t-il un meilleur moyen de trouver le RadioButton vérifié pour un groupe? Il me semble que le code ci-dessous ne devrait pas être nécessaire. Lorsque vous cochez un autre RadioButton, il sait lequel décocher… il doit donc savoir lequel est coché. Comment puis-je extraire ces informations sans faire beaucoup d'instructions if (ou un commutateur).

     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
Le code sous-jacent ne sait pas lequel décocher, il itère simplement tous les contrôles RadioButton sous le même parent du contrôle modifié et décoche celui précédemment coché.
João Angelo

1
Utilisez-vous WinForms ou ASP.Net?
SLaks

Réponses:


219

Vous pouvez utiliser LINQ:

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

Notez que cela nécessite que tous les boutons radio soient directement dans le même conteneur (par exemple, Panel ou Form) et qu'il n'y ait qu'un seul groupe dans le conteneur. Si ce n'est pas le cas, vous pouvez créer List<RadioButton>s dans votre constructeur pour chaque groupe, puis écrire list.FirstOrDefault(r => r.Checked).


Cela devrait-il être s.FirstOrDefaultplutôt que list.FirstOrDefaultdans le deuxième paragraphe de votre réponse?

@Phoenix: sest une pluralisation, pas un nom de variable.
SLaks

Excellente réponse, mais n'a pas vraiment répondu à la question principale d'OP. Voyez ma réponse.
D'Hag

pour vous les gars de vb.net, je vous épargnerai un voyage vers le convertisseur Telerik: Dim checkedButton = radConnections.Controls.OfType (Of RadioButton) (). FirstOrDefault (Function (r) r.Checked)
JoshYates1980

36

Vous pouvez câbler les CheckedEvents de tous les boutons à un seul gestionnaire. Là, vous pouvez facilement obtenir la case à cocher correcte.

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

Devrait être ceci à la place - if (((RadioButton) sender) .Checked)
Frank Tzanabetis

1
Il n'y a pas de CheckedChanged dans RadioButton de WPF d'où l'avez-vous obtenu?
Murhaf Sousli

26

Pour ceux qui n'ont pas 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;
}

12

L'OP voulait obtenir le RadioButton BY GROUP vérifié. Bien que la réponse de @SLaks soit excellente, elle ne répond pas vraiment à la question principale du PO. Pour améliorer la réponse de @SLaks, prenez simplement le LINQ un peu plus loin.

Voici un exemple de mon propre code de travail. Par WPF normal, mes RadioButtons sont contenus dans un Grid(nommé "myGrid") avec un tas d'autres types de contrôles. J'ai deux groupes RadioButton différents dans la grille.

Pour obtenir le RadioButton vérifié d'un groupe particulier:

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

Si votre code a la possibilité qu'aucun RadioButtons ne soit vérifié, utilisez SingleOrDefault()(Si je n'utilise pas de boutons à trois états, je définis toujours un bouton "IsChecked" comme sélection par défaut.)


1
r.GroupName == "GroupName" et r.IsChecked sont de types différents (bool et bool?), vous auriez dû utiliser r.IsChecked.Value, qui est de type bool.
Mike

1
try .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)car r.IsCheckedest une propriété booléenne Nullable.
Firnas

à quoi myGrid fait-il référence ici.
Unnikrishnan

@Mike Pourriez-vous dire ce que sont "radioButtons" ici?
Bella Swan

1
@BellaSwan - jetez un œil au code - vous créez une liste de tous les boutons radio et l'assignez à une variable. Et puis, sur la même variable, vous devez exécuter la sélection Where et l'affecter à rbTarget.
Mike

5

Vous pouvez utiliser l' événement CheckedChanged pour tous vos RadioButtons. Senderseront les RadioButtons non cochés et cochés.


1

Vous pouvez utiliser une méthode Extension pour itérer la collection Parent.Controls de RadioButton. Cela vous permet d'interroger d'autres RadioButtons dans la même portée. En utilisant deux méthodes d'extension, vous pouvez utiliser la première pour déterminer si des boutons radio du groupe sont sélectionnés, puis utiliser la seconde pour obtenir la sélection. Le champ RadioButton Tag peut être utilisé pour contenir un Enum pour identifier chaque RadioButton du groupe:

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

Voici un modèle d'utilisation typique:

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

1

En plus du câblage CheckedChangedEvent, on pourrait utiliser la propriété Controls "Tag" pour distinguer les boutons radio ... une alternative (spaghetti code) serait la propriété "TabIndex"; P


cela signifie que vous pouvez utiliser rapidement des boîtiers de commutation sur l'identifiant du bouton radio sélectionné (en utilisant la propriété System.Windows.Forms.Control.Tag) s'il vous plaît ne pas noter si vous ne comprenez tout simplement pas mon ajout à la question.
Binkan Salaryman

1

Parfois, dans des situations comme celle-ci, ma jeunesse me manque, quand Access était mon poison de choix, et je pouvais donner à chaque bouton radio d'un groupe sa propre valeur.

Mon hack en C # consiste à utiliser la balise pour définir la valeur, et lorsque je fais une sélection dans le groupe, je lis la valeur de la balise du radiobutton sélectionné. Dans cet exemple, directionGroup est le groupe dans lequel j'ai quatre cinq boutons radio avec "Aucun" et "NE", "SE", "NW" et "SW" comme balises sur les quatre autres boutons radio.

J'ai utilisé de manière proactive un bouton pour capturer la valeur du bouton coché, car l'attribution d'un gestionnaire d'événements à tous les événements CHeckCHanged des boutons provoque le déclenchement de CHAQUE bouton, car en changer un les change tous. Ainsi, la valeur de sender est toujours le premier RadioButton du groupe. Au lieu de cela, j'utilise cette méthode lorsque j'ai besoin de savoir laquelle est sélectionnée, avec les valeurs que je veux récupérer dans la propriété Tag de chaque 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());
    }

Pour info, j'ai testé et utilisé cela dans mon travail.

Joey


En modifiant uniquement le résultat 'FormatableString', j'ai pu utiliser le code dans mon programme. Je n'étais pas non plus au courant de radioButton Tag. Voilà comment les réponses devraient être. Grand monsieur.
Unnikrishnan

0

si vous souhaitez enregistrer la sélection dans un fichier ou autre et l'appeler plus tard, voici ce que je fais

string[] lines = new string[1];

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

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

alors appelle-le avec

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

0

Si vous souhaitez obtenir l'index du bouton radio sélectionné dans un contrôle, vous pouvez utiliser cette méthode:

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

Exemple d'utilisation:

int index = getCheckedRadioButton(panel1);

Le code n'est pas si bien testé, mais il semble que l'ordre d'index soit de gauche à droite et de haut en bas, comme lors de la lecture d'un texte. Si aucun bouton radio n'est trouvé, la méthode renvoie -1.

Mise à jour: il s'est avéré que ma première tentative n'a pas fonctionné s'il n'y a pas de bouton radio à l'intérieur du contrôle. J'ai ajouté un bloc try and catch pour résoudre ce problème, et la méthode semble maintenant fonctionner.


0

Le GroupBox a un événement Validated à cet effet, si vous utilisez 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();
     }

0

Pour les développeurs utilisant VB.NET


Private Function GetCheckedRadio(container) As RadioButton
    For Each control In container.Children
        Dim radio As RadioButton = TryCast(control, RadioButton)

        If radio IsNot Nothing AndAlso radio.IsChecked Then
            Return radio
        End If
    Next

    Return Nothing
End Function
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.