Który przycisk radiowy w grupie jest zaznaczony?

118

Korzystanie z WinForms; Czy jest lepszy sposób na znalezienie zaznaczonego RadioButton dla grupy? Wydaje mi się, że poniższy kod nie powinien być potrzebny. Kiedy sprawdzasz inny RadioButton, wtedy wie, który z nich odznaczyć… więc powinien wiedzieć, który jest zaznaczony. Jak pobrać te informacje bez wykonywania wielu instrukcji if (lub przełączania).

     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;
     }
Pałka policjanta
źródło
1
Kod bazowy nie wie, który z nich należy odznaczyć, po prostu iteruje wszystkie kontrolki RadioButton poniżej tego samego elementu nadrzędnego zmienionej kontrolki i usuwa zaznaczenie poprzednio zaznaczonej.
João Angelo
1
Czy używasz WinForms lub ASP.Net?
SLaks

Odpowiedzi:

219

Możesz użyć LINQ:

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

Zauważ, że wymaga to, aby wszystkie przyciski radiowe znajdowały się bezpośrednio w tym samym kontenerze (np. Panel lub Formularz), a kontener zawiera tylko jedną grupę. Jeśli tak nie jest, możesz utworzyć List<RadioButton>s w konstruktorze dla każdej grupy, a następnie napisz list.FirstOrDefault(r => r.Checked).

SLaks
źródło
Czy powinno to być s.FirstOrDefaultzamiast list.FirstOrDefaultw drugim akapicie Twojej odpowiedzi?
@Phoenix: sto liczba mnoga , a nie nazwa zmiennej.
SLaks
Doskonała odpowiedź, ale tak naprawdę nie odpowiedział na główne pytanie OP. Zobacz moją odpowiedź.
D'Hag
dla was vb.net, zaoszczędzę wam wycieczkę do konwertera Telerik: Dim CheckedButton = radConnections.Controls.OfType (Of RadioButton) (). FirstOrDefault (Function (r) r.Checked)
JoshYates1980
36

Możesz połączyć CheckedEvents wszystkich przycisków z jednym programem obsługi. Tam możesz łatwo uzyskać prawidłowe pole wyboru.

// 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;
    }
}
Konstabl
źródło
Powinien być zamiast tego - if (((RadioButton) sender) .Checked)
Frank Tzanabetis Kwietnia
1
Nie ma CheckedChanged w RadioButton WPF, skąd go masz?
Murhaf Sousli
26

Dla osób bez 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;
}
João Angelo
źródło
12

OP chciał uzyskać sprawdzone RadioButton WEDŁUG GRUPY. Chociaż odpowiedź @SLaks jest doskonała, tak naprawdę nie odpowiada na główne pytanie OP. Aby poprawić odpowiedź @SLaks, po prostu idź o krok dalej LINQ.

Oto przykład z mojego własnego działającego kodu. W normalnym WPF moje RadioButtons są zawarte w Grid(o nazwie „myGrid”) z kilkoma innymi typami kontrolek. Mam dwie różne grupy RadioButton w siatce.

Aby pobrać zaznaczony element RadioButton z określonej grupy:

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

Jeśli w Twoim kodzie nie ma możliwości sprawdzania RadioButtons, użyj SingleOrDefault()(Jeśli nie używam przycisków trójstanowych, zawsze ustawiam jeden przycisk „IsChecked” jako domyślny).

D'Hag
źródło
1
r.GroupName == "GroupName" i r.IsChecked są różnych typów (bool i bool?), powinieneś był użyć r.IsChecked.Value, który jest typu bool.
Mike
1
try, .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)ponieważ r.IsCheckedwłaściwość bool dopuszcza wartość null.
Firnas
do czego odnosi się myGrid.
Unnikrishnan
@Mike Czy możesz powiedzieć, co to jest „radioButtons” tutaj?
Bella Swan
1
@BellaSwan - spójrz na kod - tworzysz listę wszystkich przycisków radiowych i przypisujesz ją do zmiennej. Następnie na tej samej zmiennej musisz uruchomić wybór Where i przypisać go do rbTarget.
Mike
5

Możesz użyć zdarzenia CheckedChanged dla wszystkich swoich RadioButtons. Senderbędą niezaznaczone i zaznaczone RadioButtons.

tanascius
źródło
1

Możesz użyć metody Extension, aby wykonać iterację kolekcji Parent.Controls RadioButton. Pozwala to na wysyłanie zapytań do innych RadioButtons w tym samym zakresie. Korzystając z dwóch metod rozszerzania, możesz użyć pierwszej, aby określić, czy wybrane są jakiekolwiek RadioButtons w grupie, a następnie użyć drugiej, aby uzyskać zaznaczenie. Pole Tag RadioButton może służyć do przechowywania Enum w celu zidentyfikowania każdego RadioButton w grupie:

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

Oto typowy wzorzec użycia:

if(!MyRadioButton.IsRadioSelected()) {
   MessageBox.Show("No radio selected.");
   return;
}
int selection = MyRadioButton.GetRadioSelection;
James McManus
źródło
1

Oprócz okablowania CheckedChangedEvent można by użyć właściwości Controls "Tag" do rozróżnienia przycisków radiowych ... alternatywą (kodu spaghetti) byłaby właściwość "TabIndex"; P

Binkan Salaryman
źródło
oznacza to, że możesz szybko użyć przełączników na wybranym identyfikatorze radiobutton (używając właściwości System.Windows.Forms.Control.Tag), nie oceniaj niżej, jeśli po prostu nie rozumiesz mojego dodatku do pytania.
Binkan Salaryman,
1

Czasami w takich sytuacjach tęsknię za młodością, kiedy Access był moją wybraną trucizną i mogłem nadać każdemu przyciskowi w grupie własną wartość.

Moja sztuczka w C # polega na używaniu tagu do ustawiania wartości, a kiedy dokonuję wyboru z grupy, czytam wartość tagu wybranego radiobutton. W tym przykładzie directionGroup to grupa, w której mam cztery pięć przycisków radiowych z tagami „None” i „NE”, „SE”, „NW” i „SW” na pozostałych czterech radiobuttons.

Aktywnie użyłem przycisku do przechwycenia wartości zaznaczonego przycisku, ponieważ przypisanie jednego programu obsługi zdarzenia do zdarzenia CHeckCHanged wszystkich przycisków powoduje uruchomienie KAŻDEGO przycisku, ponieważ zmiana jednego zmienia je wszystkie. Zatem wartością nadawcy jest zawsze pierwszy element RadioButton w grupie. Zamiast tego używam tej metody, gdy muszę dowiedzieć się, która z nich jest wybrana, z wartościami, które chcę pobrać we właściwości Tag każdego 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, przetestowałem i wykorzystałem to w mojej pracy.

Joey

Joseph Morgan
źródło
Modyfikując tylko wynik „FormatableString”, mogłem użyć kodu w moim programie. Nie wiedziałem również o tagu radioButton. Tak powinny wyglądać odpowiedzi. Wielki Panie.
Unnikrishnan
0

jeśli chcesz zapisać zaznaczenie do pliku lub innego i zadzwonić później, oto co robię

string[] lines = new string[1];

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

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

następnie zadzwoń do tego za pomocą

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

Jeśli chcesz uzyskać indeks wybranego przycisku radiowego wewnątrz kontrolki, możesz użyć tej metody:

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

Przykładowe zastosowanie:

int index = getCheckedRadioButton(panel1);

Kod nie jest dobrze przetestowany, ale wydaje się, że kolejność indeksów jest od lewej do prawej i od góry do dołu, jak podczas czytania tekstu. Jeśli nie zostanie znaleziony żaden przycisk radiowy, metoda zwraca -1.

Aktualizacja: Okazało się, że moja pierwsza próba nie zadziałała, jeśli w kontrolce nie ma przycisku radiowego. Dodałem blok try i catch, aby to naprawić, i metoda wydaje się teraz działać.

matsolof
źródło
0

GroupBox ma w tym celu zdarzenie Validated, jeśli używasz 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();
     }
Bede Amarasekara
źródło
0

Dla programistów używających 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

źródło