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

Posted

技术标签:

【中文标题】选中组中的哪个单选按钮?【英文标题】:Which Radio button in the group is checked? 【发布时间】:2010-12-20 08:28:54 【问题描述】:

使用 WinForms;有没有更好的方法来为一个组找到选中的 RadioButton?在我看来,下面的代码应该是不必要的。当您选中一个不同的 RadioButton 时,它就知道要取消选中哪个……所以它应该知道哪个被选中。如何在不执行大量 if 语句(或 switch)的情况下提取这些信息。

     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;
     

【问题讨论】:

底层代码不知道要取消选中哪一个,它只是迭代更改控件的同一父级下的所有 RadioButton 控件,并取消选中之前选中的那个。 您使用的是 WinForms 还是 ASP.Net? 【参考方案1】:

你可以使用 LINQ:

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

请注意,这要求所有单选按钮都直接位于同一个容器中(例如,面板或表单),并且容器中只有一组。如果不是这样,您可以在每个组的构造函数中创建List&lt;RadioButton&gt;s,然后编写list.FirstOrDefault(r =&gt; r.Checked)

【讨论】:

答案的第二段应该是s.FirstOrDefault 而不是list.FirstOrDefault @Phoenix: s 是复数形式,不是变量名。 优秀的答案,但并没有真正回答 OP 的主要问题。看我的回答。 为你们 vb.net 伙计们,我会为你们省去 Telerik 转换器的旅行: Dim checkedButton = radConnections.Controls.OfType(Of RadioButton)().FirstOrDefault(Function(r) r.已选中)【参考方案2】:

您可以将所有按钮的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) WPF 的 RadioButton 中没有 CheckedChanged 你是从哪里得到的?【参考方案3】:

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

【讨论】:

【参考方案4】:

OP 想要按组获取选中的 RadioButton。虽然@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”设置为默认选择。)

【讨论】:

r.GroupName == "GroupName" 和 r.IsChecked 是不同的类型(bool 和 bool?),你应该使用 r.IsChecked.Value,它是 bool 类型的。 尝试.Where(r =&gt; r.GroupName == "GroupName" &amp;&amp; r.IsChecked == true),因为r.IsChecked 是可为空的布尔属性。 myGrid 在这里指的是什么。 @Mike 你能告诉这里的“radioButtons”是什么吗? @BellaSwan - 查看代码 - 您创建所有单选按钮的列表并将其分配给变量。然后,在同一个变量上,您需要运行 Where 选择并将其分配给 rbTarget。【参考方案5】:

您可以为所有 RadioButtons 使用 CheckedChanged 事件。 Sender 将是未选中和选中的 RadioButtons。

【讨论】:

【参考方案6】:

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

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

我主动使用一个按钮来捕获选中按钮的值,因为将一个事件处理程序分配给所有按钮的 CCheckCHanged 事件会导致每个按钮触发,因为更改一个会改变所有按钮。所以 sender 的值始终是组中的第一个 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 标签。答案应该是这样的。伟大的先生。【参考方案7】:

您可以使用扩展方法来迭代 RadioButton 的 Parent.Controls 集合。这允许您查询同一范围内的其他 RadioButton。使用两种扩展方法,您可以使用第一种确定组中是否有任何 RadioButtons 被选中,然后使用第二种获取选择。 RadioButton Tag 字段可用于保存 Enum 以标识组中的每个 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;

【讨论】:

【参考方案8】:

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

【讨论】:

这意味着您可以在选定的单选按钮 id 上使用快速切换大小写(使用属性 System.Windows.Forms.Control.Tag)如果您只是不理解我对问题的补充,请不要打分.【参考方案9】:

如果您想将选择保存到文件或任何其他文件并稍后调用它,我会这样做

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;

【讨论】:

【参考方案10】:

如果你想获取控件内选中单选按钮的索引,你可以使用这个方法:

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 块来解决这个问题,现在该方法似乎有效。

【讨论】:

【参考方案11】:

如果您使用的是 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();
     

【讨论】:

【参考方案12】:

对于使用 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

【讨论】:

【参考方案13】:

又一次尝试 - 使用事件 lambda 表达式

在表单初始化时,可以将单个事件处理程序分配给组框中的所有 RadioButton 类型的控件,并使用 .tabIndex 或 .tag 属性来标识在更改时检查的选项。

这样你可以一次性订阅每个单选按钮的任何事件

int priceOption = 0;
foreach (RadioButton rbtn in grp_PriceOpt.Controls.OfType<RadioButton>())

    rbtn.CheckedChanged += (o, e) =>
    
        var button = (RadioButton)o;
        if (button.Checked)
        
            priceOption = button.TabIndex;
        
    ;

由于事件仅分配给单选按钮,因此不会对发送者进行类型检查。

还要注意,当我们循环所有按钮时,这可能是分配数据属性、更改文本等的绝佳时机。

【讨论】:

以上是关于选中组中的哪个单选按钮?的主要内容,如果未能解决你的问题,请参考以下文章

我想在页面加载时检查某些单选按钮组中的某些特定单选按钮?

如何检查单选按钮是不是在 Android 的单选组中被选中?

使用 jQuery 清除单选按钮组中的错误时遇到问题

jQuery确定在一个单选组中是否至少选中了一个单选按钮

如何取消选中或清除单选按钮组?

验证单选按钮被选中