【问题标题】:Grouping Windows Forms Radiobuttons with different parent controls in C#在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组
【发布时间】:2011-06-05 08:48:29
【问题描述】:

我有一个 Windows 窗体应用程序,其中有许多单选按钮。这些 RadioButtons 放置在 FlowLayoutPanel 中,它会自动为我安排它们。直接添加到 FlowLayoutPanel 的所有 RadioButton 都被分组,这意味着我只能选择其中一个。但是,其中一些 RadioButtons 与 TextBox 配对,因此我可以在那里提供一些参数。但是为了妥善安排这一切,我在 FlowLayoutPanel 中添加了一个 Panel 控件,这样我就可以自己控制 RadioButton 和 TextBox 相对于彼此的对齐方式。

这些 RadioButton 现在有自己的面板作为父控件,因此不再与其他 RadioButton 一起包含在单选组中。我读到 System.Web.UI 命名空间中的 RadioButtons 具有 GroupName 属性,但不幸的是,它们的 System.Windows.Forms 对应项缺少此属性。还有其他方法可以对这些单选按钮进行分组吗?我必须自己处理 onClick 事件吗?

谢谢, 杰瑞

【问题讨论】:

  • 通常我们会使用分组框来分组单选按钮..

标签: c# winforms radio-button


【解决方案1】:

恐怕您将不得不手动处理...实际上还不错,您可能只需将所有 RadioButton 存储在一个列表中,并为所有这些使用单个事件处理程序:

private List<RadioButton> _radioButtonGroup = new List<RadioButton>();
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
    RadioButton rb = (RadioButton)sender;
    if (rb.Checked)
    {
        foreach(RadioButton other in _radioButtonGroup)
        {
            if (other == rb)
            {
                continue;
            }
            other.Checked = false;
        }
    }
}

【讨论】:

  • 我担心会是这样。不过应该问题不大。感谢您的帮助。
  • 修复:rb.Checked = false; => other.Checked = false;
  • @maxirby,我不明白你的评论......你是什么意思?
【解决方案2】:

我同意@JonH - 使用标签是最干净的方法(恕我直言)

  private void FormLoad(object sender, EventArgs e)
  {
     radioCsv.Tag = DataTargetTypes.CsvFile;
     radioTabbed.Tag = DataTargetTypes.TxtFile;
     radioSas.Tag = DataTargetTypes.SasFile;
  }

  private void RadioButtonCheckedChanged(object sender, EventArgs e)
  {
     var radio = (RadioButton) sender;
     this.DataDestinationType = (DataTargetTypes)radio.Tag;
  }

【讨论】:

    【解决方案3】:

    与第一个答案相比,这里有一点改进:创建一个 RadioGroup 类,该类封装了分组功能并添加了对标准键盘导航(向上/向下键)的支持,并使选项卡工作。

    要使用它,只需在表单中声明一个 RadioGroup 成员并新建它(在 InitializeComponent() 之后),并以正确的顺序在组中传递您想要的所有单选按钮。

    public class RadioGroup
    {
        List<RadioButton> _radioButtons;
    
        public RadioGroup(params RadioButton[] radioButtons)
        {
            _radioButtons = new List<RadioButton>(radioButtons);
            foreach (RadioButton radioButton in _radioButtons)
            {
                radioButton.TabStop = false;
                radioButton.KeyUp += new KeyEventHandler(radioButton_KeyUp);
                radioButton.CheckedChanged += new EventHandler(radioButton_CheckedChanged);
            }
            _radioButtons[0].TabStop = true;
        }
    
        void radioButton_KeyUp(object sender, KeyEventArgs e)
        {
            e.Handled = true;
            RadioButton radioButton = (RadioButton)sender;
            int index = _radioButtons.IndexOf(radioButton);
    
            if (e.KeyCode == Keys.Down)
            {
                index++;
                if (index >= _radioButtons.Count)
                {
                    index = 0;
                }
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Up)
            {
                index--;
                if (index < 0)
                {
                    index = _radioButtons.Count - 1;
                }
                e.Handled = true;
            }
    
            radioButton = _radioButtons[index];
            radioButton.Focus();
            radioButton.Select();
        }
    
        void radioButton_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton currentRadioButton = (RadioButton)sender;
    
            if (currentRadioButton.Checked)
            {
                foreach (RadioButton radioButton in _radioButtons)
                {
                    if (!radioButton.Equals(currentRadioButton))
                    {
                        radioButton.Checked = false;
                    }
                }
            }
        }
    }
    

    一个警告:向上/向下键不能很好地与现有的 RadioButton 类一起使用,因为它已经处理了向上/向下键。将其修复为 RadioButton 的子类并关闭对上/下键的处理的一种简单方法:

    public class RadioButtonEx : RadioButton
    {
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Up || keyData == Keys.Down)
            {
                return true;
            }
    
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
    

    【讨论】:

      【解决方案4】:

      @Jerry,我对 Windows 窗体不太熟悉,但我会试一试。如果有一个名为 Tag 的属性,您可以使用唯一的标签标记每个单选按钮。

      【讨论】:

        猜你喜欢
        • 2011-01-11
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 2014-05-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 2013-01-25
        相关资源
        最近更新 更多