Quale pulsante di opzione nel gruppo è selezionato?


118

Utilizzo di WinForms; C'è un modo migliore per trovare il RadioButton selezionato per un gruppo? Mi sembra che il codice qui sotto non dovrebbe essere necessario. Quando controlli un altro RadioButton, allora sa quale deselezionare ... quindi dovrebbe sapere quale è selezionato. Come estraggo queste informazioni senza fare molte istruzioni if ​​(o un interruttore).

     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
Il codice sottostante non sa quale deselezionare, itera semplicemente tutti i controlli RadioButton sotto lo stesso genitore del controllo modificato e deseleziona quello precedentemente selezionato.
João Angelo,

1
Stai usando WinForms o ASP.Net?
SLaks il

Risposte:


219

Puoi usare LINQ:

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

Si noti che ciò richiede che tutti i pulsanti di opzione siano direttamente nello stesso contenitore (ad esempio, Pannello o Modulo) e che nel contenitore sia presente un solo gruppo. Se non è così, potresti creare List<RadioButton>s nel tuo costruttore per ogni gruppo, quindi scrivere list.FirstOrDefault(r => r.Checked).


Dovrebbe essere questo s.FirstOrDefaultinvece che list.FirstOrDefaultnel secondo paragrafo della tua risposta?

@ Phoenix: sè una pluralizzazione, non un nome di variabile.
SLaks

Ottima risposta, ma non ha veramente risposto alla domanda principale di OP. Vedi la mia risposta.
D'Hag

per voi vb.net ragazzi, vi risparmierò un viaggio al convertitore Telerik: Dim CheckButton = radConnections.Controls.OfType (Of RadioButton) (). FirstOrDefault (Function (r) r.Checked)
JoshYates1980

36

Puoi collegare i CheckedEvents di tutti i pulsanti a un gestore. Lì puoi facilmente ottenere la casella di controllo corretta.

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

Dovrebbe essere questo invece - if (((RadioButton) sender) .Checked)
Frank Tzanabetis

1
Non c'è CheckedChanged nel RadioButton di WPF da dove l'hai preso?
Murhaf Sousli

26

Per quelli senza 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 voleva ottenere il RadioButton controllato BY GROUP. Sebbene la risposta di @SLaks sia eccellente, in realtà non risponde alla domanda principale dell'OP. Per migliorare la risposta di @SLaks, fai un ulteriore passo avanti con LINQ.

Ecco un esempio dal mio codice funzionante. Per normale WPF, i miei RadioButtons sono contenuti in un Grid(denominato "myGrid") con un mucchio di altri tipi di controlli. Ho due diversi gruppi RadioButton nella griglia.

Per ottenere il RadioButton selezionato da un particolare gruppo:

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

Se il tuo codice ha la possibilità che nessun RadioButtons venga controllato, usa SingleOrDefault()(Se non sto usando i pulsanti a tre stati, imposto sempre un pulsante "IsChecked" come selezione predefinita.)


1
r.GroupName == "GroupName" e r.IsChecked sono di diversi tipi (bool e bool?), avresti dovuto usare r.IsChecked.Value, che è di tipo bool.
Mike

1
provare .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)perché r.IsCheckedè una proprietà bool nullable.
Firnas

a cosa si riferisce myGrid qui.
Unnikrishnan

@Mike Potresti dire cos'è "radioButtons" qui?
Bella Swan

1
@BellaSwan - dai un'occhiata al codice - crei un elenco di tutti i pulsanti di opzione e lo assegni a una variabile. Quindi, sulla stessa variabile è necessario eseguire la selezione Where e assegnarla a rbTarget.
Mike

5

Puoi utilizzare l' evento CheckedChanged per tutti i tuoi RadioButtons. Sendersaranno i RadioButtons deselezionati e selezionati.


1

Puoi usare un metodo Extension per iterare la raccolta Parent.Controls di RadioButton. Ciò consente di interrogare altri RadioButton nello stesso ambito. Utilizzando due metodi di estensione, è possibile utilizzare il primo per determinare se sono selezionati i RadioButtons nel gruppo, quindi utilizzare il secondo per ottenere la selezione. Il campo RadioButton Tag può essere utilizzato per contenere un Enum per identificare ogni RadioButton nel gruppo:

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

Ecco uno schema di utilizzo tipico:

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

1

Oltre al cablaggio CheckedChangedEvent si potrebbe usare la proprietà Controls "Tag" per distinguere tra i pulsanti radio ... un'alternativa (codice spaghetti) sarebbe la proprietà "TabIndex"; P


significa che puoi usare rapidamente switch-case sull'id del radiobutton selezionato (usando la proprietà System.Windows.Forms.Control.Tag) per favore non votare se semplicemente non capisci la mia aggiunta alla domanda.
Binkan Salaryman

1

A volte in situazioni come questa mi manca la mia giovinezza, quando Access era il mio veleno preferito e potevo dare a ogni pulsante di opzione in un gruppo il proprio valore.

Il mio trucco in C # è usare il tag per impostare il valore, e quando effettuo una selezione dal gruppo, leggo il valore del tag del radiobutton selezionato. In questo esempio, directionGroup è il gruppo in cui ho quattro cinque pulsanti radio con "Nessuno" e "NE", "SE", "NW" e "SW" come tag sugli altri quattro pulsanti radio.

Ho utilizzato in modo proattivo un pulsante per acquisire il valore del pulsante selezionato, perché l'assegnazione di un gestore di eventi a tutti gli eventi CHeckCHanged dei pulsanti causa l'attivazione di OGNI pulsante, perché cambiarne uno li cambia tutti. Quindi il valore del mittente è sempre il primo RadioButton nel gruppo. Invece, utilizzo questo metodo quando ho bisogno di scoprire quale è selezionato, con i valori che voglio recuperare nella proprietà Tag di ogni 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());
    }

Cordiali saluti, l'ho testato e utilizzato nel mio lavoro.

Joey


Modificando solo il risultato "FormatableString", sono stato in grado di utilizzare il codice nel mio programma. Inoltre non ero a conoscenza del tag radioButton. Ecco come dovrebbero essere le risposte. Grande signore.
Unnikrishnan

0

se vuoi salvare la selezione su file o altro e richiamarla in seguito, ecco cosa faccio

string[] lines = new string[1];

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

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

quindi chiamalo con

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

0

Se vuoi ottenere l'indice del radio button selezionato all'interno di un controllo puoi usare questo metodo:

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

Esempio di utilizzo:

int index = getCheckedRadioButton(panel1);

Il codice non è ben testato, ma sembra che l'ordine dell'indice sia da sinistra a destra e dall'alto verso il basso, come quando si legge un testo. Se non viene trovato alcun pulsante di opzione, il metodo restituisce -1.

Aggiornamento: si è scoperto che il mio primo tentativo non ha funzionato se non c'è alcun pulsante di opzione all'interno del controllo. Ho aggiunto un blocco try and catch per risolverlo e il metodo ora sembra funzionare.


0

Il GroupBox ha un evento convalidato per questo scopo, se stai usando 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

Per gli sviluppatori che utilizzano 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.