【问题标题】:How do I group Windows Form radio buttons?如何对 Windows 窗体单选按钮进行分组?
【发布时间】:2011-01-11 19:17:12
【问题描述】:

如何在 Windows 窗体应用程序中对单选按钮进行分组(很像 ASP.NET 的单选按钮列表!)?

所以我可以在从选项中选择的每个案例之间切换。

【问题讨论】:

标签: c# .net winforms radio-button


【解决方案1】:

共享容器内的所有单选按钮默认情况下在同一个组中。 意味着,如果您选中其中一个 - 其他人将不被选中。 如果要创建独立的单选按钮组,则必须将它们置于不同的容器中,例如Group Box,或通过后面的代码控制它们的Checked状态。

【讨论】:

    【解决方案2】:

    将单选按钮放在 GroupBox 内(或其他面板)

    【讨论】:

      【解决方案3】:

      如果您不能将它们放入一个容器中,那么您必须编写代码来更改每个 RadioButtonchecked 状态:

      private void rbDataSourceFile_CheckedChanged(object sender, EventArgs e)
      {
          rbDataSourceNet.Checked = !rbDataSourceFile.Checked;
      }
      
      private void rbDataSourceNet_CheckedChanged(object sender, EventArgs e)
      {
        rbDataSourceFile.Checked = !rbDataSourceNet.Checked;
      }
      

      【讨论】:

      • 这会让你陷入无限循环,,,
      【解决方案4】:

      GroupBox更好。但不仅是group box,你也可以使用Panels(System.Windows.Forms.Panel)。

      • 这在您设计 Internet 协议版本 4 设置对话框时非常有用。(用您的电脑(Windows)检查它,然后您就可以理解行为)

      【讨论】:

        【解决方案5】:

        不带面板的单选按钮

        public class RadioButton2 : RadioButton
        {
           public string GroupName { get; set; }
        }
        
        private void RadioButton2_Clicked(object sender, EventArgs e)
        {
            RadioButton2 rb = (sender as RadioButton2);
        
            if (!rb.Checked)
            {
               foreach (var c in Controls)
               {
                   if (c is RadioButton2 && (c as RadioButton2).GroupName == rb.GroupName)
                   {
                      (c as RadioButton2).Checked = false;
                   }
               }
        
               rb.Checked = true;
            }
        }
        
        private void Form1_Load(object sender, EventArgs e)
        {
            //a group
            RadioButton2 rb1 = new RadioButton2();
            rb1.Text = "radio1";
            rb1.AutoSize = true;
            rb1.AutoCheck = false;
            rb1.Top = 50;
            rb1.Left = 50;
            rb1.GroupName = "a";
            rb1.Click += RadioButton2_Clicked;
            Controls.Add(rb1);
        
            RadioButton2 rb2 = new RadioButton2();
            rb2.Text = "radio2";
            rb2.AutoSize = true;
            rb2.AutoCheck = false;
            rb2.Top = 50;
            rb2.Left = 100;
            rb2.GroupName = "a";
            rb2.Click += RadioButton2_Clicked;
            Controls.Add(rb2);
        
            //b group
            RadioButton2 rb3 = new RadioButton2();
            rb3.Text = "radio3";
            rb3.AutoSize = true;
            rb3.AutoCheck = false;
            rb3.Top = 80;
            rb3.Left = 50;
            rb3.GroupName = "b";
            rb3.Click += RadioButton2_Clicked;
            Controls.Add(rb3);
        
            RadioButton2 rb4 = new RadioButton2();
            rb4.Text = "radio4";
            rb4.AutoSize = true;
            rb4.AutoCheck = false;
            rb4.Top = 80;
            rb4.Left = 100;
            rb4.GroupName = "b";
            rb4.Click += RadioButton2_Clicked;
            Controls.Add(rb4);
        }
        

        【讨论】:

          【解决方案6】:

          将组的所有单选按钮放入容器对象中,例如 PanelGroupBox。这将在 Windows 窗体中自动将它们组合在一起。

          【讨论】:

          • @mohammadsadeghsaati 问题是关于 Windows 窗体 RadioButton,它不公开 GroupName 属性。
          • @UweB 如果由于任何问题而无法添加组框和面板怎么办,比如说我的表单上没有太多空间。然后呢?
          • @MuhammadSaqib 这是不可能的,因为面板可以是零尺寸的。我的意思是具有不可见边框且没有边距的面板与普通形式相同。如果您应该在表格等中分组,只需使用右侧面板 - TableLayoutPanel
          【解决方案7】:

          我喜欢 WPF 中对 RadioButtons 进行分组的概念。有一个属性GroupName 指定哪些 RadioButton 控件是互斥的 (http://msdn.microsoft.com/de-de/library/system.windows.controls.radiobutton.aspx)。

          于是我为WinForms写了一个支持这个特性的派生类:

          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Text;
          using System.Windows.Forms;
          using System.Diagnostics;
          using System.Windows.Forms.VisualStyles;
          using System.Drawing;
          using System.ComponentModel;
          
          namespace Use.your.own
          {
              public class AdvancedRadioButton : CheckBox
              {
                  public enum Level { Parent, Form };
          
                  [Category("AdvancedRadioButton"),
                  Description("Gets or sets the level that specifies which RadioButton controls are affected."),
                  DefaultValue(Level.Parent)]
                  public Level GroupNameLevel { get; set; }
          
                  [Category("AdvancedRadioButton"),
                  Description("Gets or sets the name that specifies which RadioButton controls are mutually exclusive.")]
                  public string GroupName { get; set; }
          
                  protected override void OnCheckedChanged(EventArgs e)
                  {
                      base.OnCheckedChanged(e);
          
                      if (Checked)
                      {
                          var arbControls = (dynamic)null;
                          switch (GroupNameLevel)
                          {
                              case Level.Parent:
                                  if (this.Parent != null)
                                      arbControls = GetAll(this.Parent, typeof(AdvancedRadioButton));
                                  break;
                              case Level.Form:
                                  Form form = this.FindForm();
                                  if (form != null)
                                      arbControls = GetAll(this.FindForm(), typeof(AdvancedRadioButton));
                                  break;
                          }
                          if (arbControls != null)
                              foreach (Control control in arbControls)
                                  if (control != this &&
                                      (control as AdvancedRadioButton).GroupName == this.GroupName)
                                      (control as AdvancedRadioButton).Checked = false;
                      }
                  }
          
                  protected override void OnClick(EventArgs e)
                  {
                      if (!Checked)
                          base.OnClick(e);
                  }
          
                  protected override void OnPaint(PaintEventArgs pevent)
                  {
                      CheckBoxRenderer.DrawParentBackground(pevent.Graphics, pevent.ClipRectangle, this);
          
                      RadioButtonState radioButtonState;
                      if (Checked)
                      {
                          radioButtonState = RadioButtonState.CheckedNormal;
                          if (Focused)
                              radioButtonState = RadioButtonState.CheckedHot;
                          if (!Enabled)
                              radioButtonState = RadioButtonState.CheckedDisabled;
                      }
                      else
                      {
                          radioButtonState = RadioButtonState.UncheckedNormal;
                          if (Focused)
                              radioButtonState = RadioButtonState.UncheckedHot;
                          if (!Enabled)
                              radioButtonState = RadioButtonState.UncheckedDisabled;
                      }
          
                      Size glyphSize = RadioButtonRenderer.GetGlyphSize(pevent.Graphics, radioButtonState);
                      Rectangle rect = pevent.ClipRectangle;
                      rect.Width -= glyphSize.Width;
                      rect.Location = new Point(rect.Left + glyphSize.Width, rect.Top);
          
                      RadioButtonRenderer.DrawRadioButton(pevent.Graphics, new System.Drawing.Point(0, rect.Height / 2 - glyphSize.Height / 2), rect, this.Text, this.Font, this.Focused, radioButtonState);
                  }
          
                  private IEnumerable<Control> GetAll(Control control, Type type)
                  {
                      var controls = control.Controls.Cast<Control>();
          
                      return controls.SelectMany(ctrl => GetAll(ctrl, type))
                                                .Concat(controls)
                                                .Where(c => c.GetType() == type);
                  }
              }
          }
          

          【讨论】:

          • 在我需要在 TableLayoutPanel 内的组中使用 RadioButtons 的情况下,这对我非常有用 - 谢谢!
          • 我正在尝试将此类用于我自己的一种表单,但无法让控件显示在组框顶部(就好像它是组框的标题一样)。它用作顶级单选按钮(id est,此单选按钮的组是表单根部的面板,组框是同级)。有没有关于如何使用这个类来实现的示例代码?
          • 我会写 IEnumerable&lt;Control&gt; arbControls = null; 而不是使用动态。 var 掩盖得更多,这就是为什么我通常在我的代码中只使用显式类型。否则,做得很好,非常感谢分享这个! +1
          【解决方案8】:

          您应该将组的所有单选按钮放在同一个容器中,例如 GroupBox 或 Panel。

          【讨论】:

          • 当您有多层嵌套面板时,它会变得复杂,例如当您尝试执行something that looks like this 时。单选按钮与其父级发生冲突。
          【解决方案9】:

          看看将你的单选按钮放在GroupBox中。

          【讨论】:

          • GroupBox 与单选按钮完全无关。任何容器都可以。
          猜你喜欢
          • 2012-06-12
          • 1970-01-01
          • 2014-05-28
          • 2011-06-05
          • 1970-01-01
          • 2017-07-13
          • 2011-01-23
          • 2011-11-01
          • 2013-06-14
          相关资源
          最近更新 更多