在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组
Posted
技术标签:
【中文标题】在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组【英文标题】:Grouping Windows Forms Radiobuttons with different parent controls in C# 【发布时间】: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 事件吗?
谢谢, 杰瑞
【问题讨论】:
通常我们会使用分组框来分组单选按钮.. 【参考方案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 的属性,您可以使用唯一的标签标记每个单选按钮。
【讨论】:
以上是关于在 C# 中使用不同的父控件对 Windows 窗体单选按钮进行分组的主要内容,如果未能解决你的问题,请参考以下文章
C# webBrowser控件禁用alert,confirm之类的弹窗解决方案