Welches Optionsfeld in der Gruppe ist aktiviert?

118

Verwenden von WinForms; Gibt es eine bessere Möglichkeit, den aktivierten RadioButton für eine Gruppe zu finden? Es scheint mir, dass der folgende Code nicht notwendig sein sollte. Wenn Sie einen anderen RadioButton aktivieren, weiß dieser, welcher deaktiviert werden muss. Daher sollte er wissen, welcher aktiviert ist. Wie kann ich diese Informationen abrufen, ohne viele if-Anweisungen (oder einen Schalter) auszuführen?

     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;
     }
Billy
quelle
1
Der zugrunde liegende Code weiß nicht, welcher Code deaktiviert werden soll. Er iteriert lediglich alle RadioButton-Steuerelemente unter demselben übergeordneten Element des geänderten Steuerelements und deaktiviert das zuvor überprüfte.
João Angelo
1
Verwenden Sie WinForms oder ASP.Net?
SLaks

Antworten:

219

Sie könnten LINQ verwenden:

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

Beachten Sie, dass sich dazu alle Optionsfelder direkt im selben Container befinden müssen (z. B. Bedienfeld oder Formular) und dass sich nur eine Gruppe im Container befindet. Wenn das nicht der Fall ist, könnten Sie machenList<RadioButton> in Ihrem Konstruktor für jede Gruppe s erstellen und dann schreiben list.FirstOrDefault(r => r.Checked).

SLaks
quelle
Sollte das s.FirstOrDefaultstatt list.FirstOrDefaultim zweiten Absatz Ihrer Antwort sein?
@Phoenix: sist eine Pluralisierung, kein Variablenname.
SLaks
Ausgezeichnete Antwort, aber die Hauptfrage von OP wurde nicht wirklich beantwortet. Siehe meine Antwort.
D'Hag
Für euch vb.net-Leute erspare ich euch eine Reise zum Telerik-Konverter: Dim CheckedButton = radConnections.Controls.OfType (Of RadioButton) (). FirstOrDefault (Funktion (r) r.Checked)
JoshYates1980
36

Sie können die CheckedEvents aller Schaltflächen mit einem Handler verbinden. Dort können Sie leicht das richtige Kontrollkästchen erhalten.

// 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;
    }
}
Bobby
quelle
Sollte dies stattdessen sein - wenn (((RadioButton) Absender) .Checked)
Frank Tzanabetis
1
Es gibt kein CheckedChanged im RadioButton von WPF. Woher haben Sie es?
Murhaf Sousli
26

Für diejenigen ohne 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
quelle
12

Das OP wollte den überprüften RadioButton BY GROUP erhalten. Die Antwort von @SLaks ist zwar ausgezeichnet, beantwortet aber nicht wirklich die Hauptfrage des OP. Um die Antwort von @SLaks zu verbessern, gehen Sie einfach noch einen Schritt weiter.

Hier ist ein Beispiel aus meinem eigenen Arbeitscode. Gemäß normalem WPF sind meine RadioButtons in a enthaltenGrid (mit dem Namen "myGrid") zusammen mit einer Reihe anderer Steuerelementtypen enthalten. Ich habe zwei verschiedene RadioButton-Gruppen im Grid.

So erhalten Sie den aktivierten RadioButton von einer bestimmten Gruppe:

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

Wenn in Ihrem Code möglicherweise keine RadioButtons aktiviert sind, verwenden Sie SingleOrDefault()(Wenn ich keine Drei-Status-Schaltflächen verwende, habe ich immer eine Schaltfläche "IsChecked" als Standardauswahl festgelegt.)

D'Hag
quelle
1
r.GroupName == "GroupName" und r.IsChecked sind vom unterschiedlichen Typ (bool und bool?). Sie sollten r.IsChecked.Value vom Typ bool verwendet haben.
Mike
1
versuchen Sie, .Where(r => r.GroupName == "GroupName" && r.IsChecked == true)weil r.IsCheckedist nullable bool Eigenschaft.
Firnas
Worauf bezieht sich myGrid hier?
Unnikrishnan
@Mike Kannst du sagen, was "radioButtons" hier ist?
Bella Swan
1
@BellaSwan - sehen Sie sich den Code an - Sie erstellen eine Liste aller Optionsfelder und weisen sie einer Variablen zu. Und dann müssen Sie für dieselbe Variable die Where-Auswahl ausführen und sie rbTarget zuweisen.
Mike
5

Sie können das CheckedChanged- Ereignis für alle Ihre RadioButtons verwenden. Senderwerden die deaktivierten und aktivierten RadioButtons sein.

Tanascius
quelle
1

Sie können eine Erweiterungsmethode verwenden, um die Parent.Controls-Auflistung von RadioButton zu iterieren. Auf diese Weise können Sie andere RadioButtons im gleichen Bereich abfragen. Mit zwei Erweiterungsmethoden können Sie die erste verwenden, um festzustellen, ob RadioButtons in der Gruppe ausgewählt sind, und dann die zweite verwenden, um die Auswahl zu erhalten. Das RadioButton-Tag-Feld kann verwendet werden, um eine Aufzählung zur Identifizierung jedes RadioButton in der Gruppe zu speichern:

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

Hier ist ein typisches Verwendungsmuster:

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

Zusätzlich zur CheckedChangedEvent-Verkabelung könnte man die Controls-Eigenschaft "Tag" verwenden, um zwischen den Optionsfeldern zu unterscheiden. Eine (Spaghetti-Code-) Alternative wäre die Eigenschaft "TabIndex"; P.

Binkan Salaryman
quelle
Es bedeutet, dass Sie schnell Switch-Case für die ausgewählte Radiobutton-ID verwenden können (mithilfe der Eigenschaft System.Windows.Forms.Control.Tag). Bitte bewerten Sie nicht, wenn Sie meinen Zusatz zur Frage einfach nicht verstehen.
Binkan Salaryman
1

Manchmal vermisse ich in solchen Situationen meine Jugend, als Access mein Gift der Wahl war, und ich konnte jedem Optionsfeld in einer Gruppe seinen eigenen Wert geben.

Mein Hack in C # besteht darin, das Tag zum Festlegen des Werts zu verwenden. Wenn ich eine Auswahl aus der Gruppe treffe, lese ich den Wert des Tags des ausgewählten Radiobutton. In diesem Beispiel ist directionGroup die Gruppe, in der ich vier fünf Optionsfelder mit "Keine" und "NE", "SE", "NW" und "SW" als Tags auf den anderen vier Radiobuttons habe.

Ich habe proaktiv eine Schaltfläche verwendet, um den Wert der aktivierten Schaltfläche zu erfassen, da das Zuweisen eines Ereignishandlers zu allen CHeckCHanged-Ereignissen aller Schaltflächen dazu führt, dass JEDE Schaltfläche ausgelöst wird, da durch Ändern einer Schaltfläche alle geändert werden. Der Wert des Absenders ist also immer der erste RadioButton in der Gruppe. Stattdessen verwende ich diese Methode, wenn ich herausfinden möchte, welche ausgewählt ist, mit den Werten, die ich in der Tag-Eigenschaft jedes RadioButton abrufen möchte.

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

Zu Ihrer Information, ich habe dies getestet und in meiner Arbeit verwendet.

Joey

Joseph Morgan
quelle
Ich habe nur das Ergebnis 'FormatableString' geändert und konnte den Code in meinem Programm verwenden. RadioButton Tag war mir auch nicht bekannt. So sollten die Antworten sein. Großer Herr.
Unnikrishnan
0

Wenn Sie die Auswahl in einer Datei oder einer anderen Datei speichern und später aufrufen möchten, klicken Sie hier

string[] lines = new string[1];

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

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

dann nenne es mit

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

Wenn Sie den Index des ausgewählten Optionsfelds in einem Steuerelement abrufen möchten, können Sie folgende Methode verwenden:

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

Anwendungsbeispiel:

int index = getCheckedRadioButton(panel1);

Der Code ist nicht so gut getestet, aber es scheint, dass die Indexreihenfolge von links nach rechts und von oben nach unten ist, wie beim Lesen eines Textes. Wird kein Optionsfeld gefunden, gibt die Methode -1 zurück.

Update: Es stellte sich heraus, dass mein erster Versuch nicht funktioniert hat, wenn sich kein Optionsfeld im Steuerelement befindet. Ich habe einen Try-and-Catch-Block hinzugefügt, um das zu beheben, und die Methode scheint jetzt zu funktionieren.

Matsolof
quelle
0

Die GroupBox verfügt zu diesem Zweck über ein validiertes Ereignis, wenn Sie WinForms verwenden.

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
quelle
0

Für Entwickler, die VB.NET verwenden


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

quelle