【问题标题】:Radiobuttons in different group boxes不同组框中的单选按钮
【发布时间】:2013-05-29 17:10:46
【问题描述】:

这是一个非常愚蠢的问题,但仍然很烦人。

问题是我有两个组框,其中的标题有单选按钮覆盖组框标题。

有点像

(x) I want pizza
*Pizza stuff*

( ) I want Hamburger
*Hamburger stuff*

由于它们现在位于不同的组框中,因此它们都可以被选中。 有没有办法设置/强制单选按钮在同一个“组”中?就像在您设置的 HTML 中一样 name="WhatToEat" value="Pizza" 第一个值,然后 name="WhatToEat" value="Hamburger"

或者我可以将组框的标题设置为像单选按钮或其他东西吗?

当然,我可以将单选按钮放在 grop 框之外,但我认为将标题作为单选按钮最有意义并且看起来更好。

【问题讨论】:

    标签: vb.net winforms visual-studio-2010 radio-button


    【解决方案1】:

    只需在运行时将它们移动到表单。使用 PointToScreen() 和 PointToClient() 将它们保持在与您在设计时放置它们的位置相同的位置。因此,您可以将“RadioButton1”、“RadioButton2”和“RadioButton3”替换为您的标题 RadioButtons:

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim RadioTitles() As RadioButton = {RadioButton1, RadioButton2, RadioButton3}
        For Each rb As RadioButton In RadioTitles
            Dim pt As Point = Me.PointToClient(rb.PointToScreen(New Point(0, 0)))
            Me.Controls.Add(rb)
            rb.Location = pt
            rb.BringToFront()
        Next
    End Sub
    

    *您可以将一个值放入每个 RadioButton 的 Tag() 属性中,该值应该是“标题”,然后搜索这些值,而不是将它们硬编码到数组中。或者你可以用某种方式命名它们。

    编辑:您可以使“标题”单选按钮在检查时启用/禁用其关联的 GroupBox,如下所示:

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim RadioTitles() As RadioButton = {RadioButton1, RadioButton2, RadioButton3}
        For Each rb As RadioButton In RadioTitles
            rb.Parent.Enabled = False
            rb.Tag = rb.Parent
            AddHandler rb.CheckedChanged, AddressOf TitleRadioButtons_CheckedChanged
    
            Dim pt As Point = Me.PointToClient(rb.PointToScreen(New Point(0, 0)))
            Me.Controls.Add(rb)
            rb.Location = pt
            rb.BringToFront()
        Next
    End Sub
    
    Private Sub TitleRadioButtons_CheckedChanged(sender As Object, e As System.EventArgs)
        Dim rb As RadioButton = DirectCast(sender, RadioButton)
        If Not IsNothing(rb.Tag) AndAlso TypeOf rb.Tag Is Control Then
            Dim ctl As Control = DirectCast(rb.Tag, Control)
            ctl.Enabled = rb.Checked
        End If
    End Sub
    

    【讨论】:

      【解决方案2】:

      您可以将GroupBox 的文本设置为空字符串并将RadioButton 放在上面。诀窍是把它放在表单上,​​但移动它看起来像是GroupBox 的一部分。但这仅在您的组框是静态且不会移动的情况下就足够了。否则最好使用@matzone 提出的解决方案。但即使在这种情况下,您也可以将所有单选按钮放在代码中的集合中,并对所有单选按钮使用唯一的事件处理程序。类似的东西

      private List<RadioButton> radioButtons;
      
      public YourFormConstructor()
      {
          InitializeComponent();
          radioButtons.Add(radio1);
          radioButtons.Add(radio2);
          radioButtons.Add(radio3);
          foreach (var radio in radioButtons)
              radio.CheckedChanged += RadioCheckedChanged;
      }
      
      private void CheckedChanged(object sender, EventArgs e)
      {
          var thisRadio = sender as RadioButton;
          if (!thisRadio.Checked)
              return;
          foreach (var radio in radioButtons)
              if (radio != thisRadio)
                  radio.Checked = false;
      }
      

      【讨论】:

        【解决方案3】:

        如果您的所有单选按钮都在表单上。您可以使用 RadioButton 变量来标记当前检查的内容。每次用户检查 RadioButton 时,如果不是当前选中的 RadioButton,则取消选中当前选中的 RadioButton,并将当前选中的 RadioButton 设置为该 RadioButton。

        这是我的代码:

        public Form1(){
          InitializeComponents();
          currentChecked = radioButton1;
        }
        //Suppose the initially checked radio is radioButton1
        RadioButton currentChecked;
        //This is the CheckedChanged event handler used for all the radiobuttons
        private void radioButtonChecked(object sender, EventArgs e)
        {
                RadioButton r = (RadioButton)sender;
                if (r != currentChecked)
                {
                    currentChecked.Checked = false;
                    currentChecked = r;
                }
        }
        

        我的代码在不使用任何循环的情况下要简单得多。它需要额外的currentChecked,但并不多。

        希望对你有帮助!

        【讨论】:

        • 这是一个非常好的解决方案!
        • 谢谢!每当我遇到像你这样的问题时,我都会这样做。 :)
        • 我不明白:“如果你的所有单选按钮都在一个表单上。”如果所有 RadioButtons 都在 Form 上,那么它们都在同一个 Group 中,并且它们已经表现出这种行为。为什么你需要代码然后取消选中最后一个 RadioButton?......他们已经自己做到了!
        • @Idle_Mind 我的意思是您可以访问 Form 类中的每个 RadioButton,但它们不会添加到 Form 的控件中。同一个窗体上的 RadioButtons 并不意味着必须将它们添加到窗体的 Controls 中。谢谢,顺便说一句,我的英语不够好,无法准确表达我想要表达的意思。
        【解决方案4】:

        很遗憾,这不是单选按钮的工作方式。

        我相信您已经知道,单选按钮从容器中获取分组。 据我所知,如果您希望能够完成您的要求,您可能需要编写自定义解决方案。例如,您可以在每个单选按钮上放置一个 事件处理程序 来触发相同的事件以取消选中其他框,例如

        radioButton1.CheckedChanged += anyRadioButton_CheckedChanged;
        radioButton2.CheckedChanged += anyRadioButton_CheckedChanged;
        radioButton3.CheckedChanged += anyRadioButton_CheckedChanged;
        
        ...
        
        private void anyRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            foreach (var control in this.Controls)
            {
                if(control is GroupBox)
                {
                    foreach (var childControl in ((GroupBox)control).Controls)
                    {
                        if (childControl is RadioButton && childControl != sender)
                        {
                            ((RadioButton)childControl).Checked = false;
                        }
                    }
                }
            }
        }
        

        【讨论】:

        • 当我们可以避免它时,我认为不建议使用循环。
        • @KingKing Care 解释为什么?
        • 请查看我的回答以了解为什么我说在这种情况下不建议使用 Loop。谢谢!
        【解决方案5】:

        不,它必须在一组..

        但是对于这种情况,您可以在 checked_change 事件中进行控制

        Private Sub RadioButton2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton2.CheckedChanged
            RadioButton1.Checked = Not RadioButton2.Checked
        End Sub
        
        Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged
            RadioButton2.Checked = Not RadioButton1.Checked
        End Sub
        

        【讨论】:

        • 这仅用于2个单选按钮,一般答案应该解决有很多单选按钮的一般情况。
        • 是的,这实际上是我提出这个问题后想出的。感觉不对,但我想在这种情况下我必须接受这个灵魂。谢谢 :)
        • @KingKing 是的,这就是我的意思。这应该是一些解决方法。如果单选按钮是由某种循环生成的,那将是另一个烦人的循环,用于检查选中的单选按钮。
        • @gubbfett : 你需要超过 2 rb 吗?
        • 实际上暂时还没有,但是看看是否有人以前这样做过并且有另一个解决方案并且实际上将他们放在同一个组中,即使他们在不同的盒子里,这仍然很有趣。作为一名网络开发人员,我认为这可以以更“正确”的方式完成。
        猜你喜欢
        • 2021-11-13
        • 2017-07-24
        • 1970-01-01
        • 1970-01-01
        • 2012-04-21
        • 1970-01-01
        • 2011-11-03
        • 2013-04-10
        • 1970-01-01
        相关资源
        最近更新 更多