在C#中,如何将不同父控件下的Windows Forms单选按钮进行分组?

11

我有一个Windows Forms应用程序,在其中我有多个单选按钮。

这些单选按钮放置在一个FlowLayoutPanel中,该控件会自动排列它们。所有直接添加到FlowLayoutPanel中的单选按钮都被分组,这意味着我只能选择其中之一。

然而,其中一些单选按钮与文本框配对,以便我可以在其中提供一些参数。但是,为了使所有内容都正确排列,我向FlowLayoutPanel中添加了一个Panel控件,以便我可以自己相对于彼此控制单选按钮和文本框的对齐方式。

这些单选按钮现在具有自己的父控件面板,因此不再包括在其他单选按钮的组中。我了解到在System.Web.UI命名空间中的单选按钮具有GroupName属性,但是不幸的是,它们在System.Windows.Forms命名空间中缺少此属性。是否有其他方法可以将这些单选按钮分组,或者我必须自己处理onClick事件呢?

谢谢, Jerry


通常我们会使用分组框来对单选按钮进行分组。 - Shashi
4个回答

13

恐怕你必须手动处理这个问题... 其实也不算太麻烦,你可以将所有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;
        }
    }
}

我担心会出现这种情况。不过应该没问题的。谢谢你的帮助。 - Jela
1
修复:rb.Checked = false; => other.Checked = false; - parzival
@maxirby,我不理解你的评论...你是什么意思? - Thomas Levesque

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

0

@Jerry,我对Windows Forms不是很熟悉,但我会尝试一下。如果有一个叫做Tag的属性,你可以给每个单选按钮打上唯一的标签。


0
这里对第一个答案进行了一点改进:创建一个RadioGroup类,封装分组功能并添加标准键盘导航(上/下键)的支持,并使得制表符(tabbing)生效。
使用它很简单,在窗体中声明一个RadioGroup成员,然后在InitializeComponent()之后new它,将您想要放入该组中的所有单选按钮按正确顺序传递进去即可。
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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接