选中组中的哪个单选按钮?


118

使用WinForms;有没有更好的方法来查找组中选中的RadioButton?在我看来,以下代码不是必需的。当您检查另一个RadioButton时,它将知道要取消选中哪个按钮。因此,它应该知道已选中了哪个按钮。如何在不执行大量if语句(或开关)的情况下提取该信息。

     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
基础代码不知道要取消选中哪一个,它只是迭代已更改控件的同一父项下的所有RadioButton控件,并取消选中先前选中的控件。
若昂·安杰洛

1
您正在使用WinForms还是ASP.Net?
SLaks

Answers:


219

您可以使用LINQ:

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

请注意,这要求所有单选按钮直接位于同一容器中(例如,面板或窗体),并且容器中只有一组。如果不是这种情况,则可以List<RadioButton>在构造函数中为每个组创建,然后编写list.FirstOrDefault(r => r.Checked)


应该用答案第二段s.FirstOrDefault代替list.FirstOrDefault吗?

@Phoenix:s是复数形式,而不是变量名。
Slaks

很好的答案,但没有真正回答OP的主要问题。看我的答案。
D'Hag

为您vb.net伙计们,我将为您节省前往Telerik转换器的旅行:Dim CheckedButton = radConnections.Controls.OfType(Of RadioButton)()。FirstOrDefault(Function(r)r.Checked)
JoshYates1980 2013年

36

您可以将所有按钮的CheckedEvents连接到一个处理程序。在那里,您可以轻松获得正确的复选框。

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

应该是这个-if((((RadioButton)sender).Checked)
Frank Tzanabetis

1
WPF的RadioButton中没有CheckedChanged,您是从哪里获得的?
Murhaf Sousli 2013年

26

对于那些没有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

OP希望获得选中的RadioButton BY GROUP。虽然@SLaks的回答很好,但它并不能真正回答OP的主要问题。要改善@SLaks的答案,只需将LINQ进一步向前即可。

这是我自己的工作代码中的一个示例。按照常规的WPF,我的RadioButtons包含在Grid(名为“ myGrid”)中,并带有其他类型的控件。我在网格中有两个不同的RadioButton组。

要从特定组获取选中的RadioButton:

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

如果您的代码有可能没有选中RadioButtons,则使用SingleOrDefault()(如果我不使用三态按钮,那么我总是将一个按钮“ IsChecked”设置为默认选项。)


1
r.GroupName ==“ GroupName”和r.IsChecked是不同的类型(bool和bool?),您应该使用r.IsChecked.Value,它是bool类型。
迈克(Mike)

1
请尝试,.Where(r => r.GroupName == "GroupName" && r.IsChecked == true)因为它r.IsChecked是可为null的bool属性。
Firnas

myGrid在这里指的是什么。
Unnikrishnan

@Mike你能告诉我什么是“ radioButtons”吗?
贝拉·斯旺

1
@BellaSwan-查看代码-创建所有单选按钮的列表并将其分配给变量。然后,在同一变量上,您需要运行Where选择并将其分配给rbTarget。
迈克,


1

您可以使用Extension方法来迭代RadioButton的Parent.Controls集合。这使您可以查询同一作用域中的其他RadioButton。使用两种扩展方法,您可以使用第一种方法确定是否选择了组中的任何RadioButton,然后使用第二种方法进行选择。RadioButton Tag字段可用于保存一个枚举,以标识组中的每个RadioButton:

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

这是一个典型的使用模式:

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

1

除了CheckedChangedEvent接线外,还可以使用Controls的“ Tag”属性来区分单选按钮...(意大利面条代码)的替代选择是“ TabIndex”属性; P


这意味着您可以在选定的单选按钮ID(使用属性System.Windows.Forms.Control.Tag)上快速使用切换大小写的按钮(如果您根本不理解我对问题的添加,请不要降低评级)。
Binkan Salaryman 2013年

1

有时在这种情况下,我想念我的青春,那时Access是我的选择毒药,我可以给组中的每个单选按钮赋予自己的价值。

我在C#中的技巧是使用标签来设置值,当我从组中进行选择时,我读取了所选单选按钮的标签的值。在此示例中,directionGroup是其中有四个五个单选按钮的组,其中“ None”和“ NE”,“ SE”,“ NW”和“ SW”作为其他四个单选按钮上的标签。

我主动使用一个按钮来捕获选中按钮的值,因为将一个事件处理程序分配给所有按钮的CHeckCHanged事件会导致EACH按钮被触发,因为更改一个按钮会全部更改。因此,发件人的值始终是组中的第一个RadioButton。取而代之的是,当我需要找出要选择的一个时,使用我想在每个RadioButton的Tag属性中检索的值的方法。

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

仅供参考,我已经在工作中测试并使用了此功能。

乔伊


仅修改'FormatableString'结果,我就可以在程序中使用该代码。我也不知道radioButton标签。这就是答案。大先生
Unnikrishnan

0

如果您要将选择保存到文件或其他任何文件中,以后再调用,请按此处

string[] lines = new string[1];

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

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

然后用

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

0

如果要获取控件内所选单选按钮的索引,可以使用此方法:

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

使用示例:

int index = getCheckedRadioButton(panel1);

该代码没有经过很好的测试,但似乎索引顺序是从左到右,从上到下,就像阅读文本时一样。如果未找到单选按钮,则该方法返回-1。

更新:事实证明,如果控件内没有单选按钮,我的第一次尝试将不起作用。我添加了一个try and catch块来解决该问题,该方法现在似乎可以工作了。


0

如果您使用的是WinForms,则GroupBox为此有一个Validated事件。

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

对于使用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.