C#:如何避免多个选中的单选按钮
C#: How to avoid multiple checked RadioButtons
一般情况下,一个Panel中一次只能勾选一个RadioButton。
现在我有一个Panel(主要是实现垂直滚动),里面有一个两列的TableLayoutPanel。通过单击 "Add row" 按钮,可以向 TLP 无限添加新行(这就是我需要面板向下滚动的原因)。
TLP 中的每一行看起来都一样:
第一列包含另一个具有一列和两行的 TLP。第一行仅包含一个 RadioButton,第二行仅包含另一个按钮。
第二列包含一个 CheckedListBox。
这么说吧,我在 TLP 中添加了 5 行。所以我有 5 个 RadioButtons。不知道为什么,但是可以一次检查所有 RadioButtons。我怎样才能避免这种情况?
这里是添加行到 TLP 的代码:
void add_newbox()
{
var new_chklistbox = new CheckedListBox{
Dock=DockStyle.Fill,
Margin=new Padding(0,0,0,3),
Location=new Point(20,0),
Size=new Size(238,94),
HorizontalScrollbar=true,
CheckOnClick=true
};
var new_radiobutton = new RadioButton{
Text="",
Dock=DockStyle.Fill,
Location=new Point(3,3),
Size=new Size(14,90),
MaximumSize=new Size(0,90)
};
new_radiobutton.Click += (sender, e) => this.focus=new_chklistbox;
var new_rembutton = new Button{
Text="-",
Dock=DockStyle.Fill,
AutoSize=true,
AutoSizeMode=AutoSizeMode.GrowAndShrink,
Margin=new Padding(0)
};
new_rembutton.Click += (sender, e) => rem_items();
var new_tbl = new TableLayoutPanel{
RowCount=2,
ColumnCount=1,
Dock=DockStyle.Fill,
Margin=new Padding(0)
};
new_tbl.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));
new_tbl.RowStyles.Add(new RowStyle(SizeType.AutoSize));
new_tbl.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
new_tbl.Controls.Add(new_radiobutton,0,0);
new_tbl.Controls.Add(new_rembutton,0,1);
tbl_groups.Controls.Add(new_tbl,0,tbl_groups.RowCount);
tbl_groups.Controls.Add(new_chklistbox,1,tbl_groups.RowCount);
}
你好,xola
使用 Radiobutton 的 GroupName 属性。
<RadioButton Content="{content}" GroupName="RadioGroupIdentifier"/>
我猜这就是你要找的东西。
编辑
没有注意到您指的是 win 表单(您可以将其写在问题中,因为标签在阅读时经常被跳过)。
但是,你应该阅读 this article from microsoft ,这里是有用的部分:
- 从 Windows 表单选项卡中拖出一个 GroupBox 或 Panel 控件
将工具箱拖到窗体上。
- 在 GroupBox 或 Panel 控件上绘制 RadioButton 控件。
一般情况下,每个 RadioButton 都默认分组在父 GroupBox 或 Panel 中。
没有其他简单的方法可以仅通过设计器来完成此操作。
您当然可以通过事件 buuuut 实现您自己的逻辑....我不建议这样做。
试试这个。它可能对你有用。
void add_newbox()
{
var new_chklistbox = new CheckedListBox{
Dock=DockStyle.Fill,
Margin=new Padding(0,0,0,3),
Location=new Point(20,0),
Size=new Size(238,94),
HorizontalScrollbar=true,
CheckOnClick=true
};
var new_radiobutton = new RadioButton{
Text="",
Dock=DockStyle.Fill,
Location=new Point(3,3),
Size=new Size(14,90),
MaximumSize=new Size(0,90)
};
//new_radiobutton.Click += (sender, e) => this.focus=new_chklistbox;
var new_rembutton = new Button{
Text="-",
Dock=DockStyle.Fill,
AutoSize=true,
AutoSizeMode=AutoSizeMode.GrowAndShrink,
Margin=new Padding(0)
};
//new_rembutton.Click += (sender, e) => rem_items();
var new_tbl = new TableLayoutPanel{
RowCount=2,
ColumnCount=1,
Dock=DockStyle.Fill,
Margin=new Padding(0)
};
var new_panel = new Panel
{
Dock = DockStyle.Fill,
AutoSize = true,
Margin = new Padding(0)
};
new_panel.Controls.Add(new_radiobutton);
new_panel.Controls.Add(new_rembutton);
new_tbl.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));
new_tbl.RowStyles.Add(new RowStyle(SizeType.AutoSize));
new_tbl.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
new_tbl.Controls.Add(new_panel, 0, 0);
要让一些单选按钮作为一个组,您应该将它们全部托管在同一个容器中。不同的 table 布局面板是不同的容器。它描述了行为。
如果出于任何原因你想保持布局不变,你需要将这些单选按钮的 AutoCheck
属性 设置为 true 并处理它们的 Click
事件以检查只需单击一个并取消选中其余的。
例子
private void Form1_Load(object sender, EventArgs e)
{
var radios = GetChildren(tableLayoutPanel1).OfType<RadioButton>();
foreach (var radio in radios)
{
radio.AutoCheck=false;
radio.Click += (obj, arg) =>
{
radio.Checked = true;
foreach(var r in radios)
if (r != radio)
r.Checked = false;
};
}
}
IEnumerable<Control> GetChildren(Control control)
{
foreach (Control c1 in control.Controls)
{
yield return c1;
foreach (Control c2 in GetChildren(c1))
yield return c2;
}
}
我对您的代码做了一些改动,并对旧代码进行了注释。请试试看。在此代码中,我在现有 TPL 控件中添加新行,而不是每次都添加新的 TLP。
void add_newbox()
{
var new_chklistbox = new CheckedListBox
{
Dock = DockStyle.Fill,
Margin = new Padding(0, 0, 0, 3),
Location = new Point(20, 0),
Size = new Size(238, 94),
HorizontalScrollbar = true,
CheckOnClick = true
};
var new_radiobutton = new RadioButton
{
Text = "",
Dock = DockStyle.Fill,
Location = new Point(3, 3),
Size = new Size(14, 90),
MaximumSize = new Size(0, 90)
};
new_radiobutton.Click += (sender, e) => this.focus = new_chklistbox;
var new_rembutton = new Button
{
Text = "-",
Dock = DockStyle.Fill,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
Margin = new Padding(0)
};
new_rembutton.Click += (sender, e) => rem_items();
//var new_tbl = new TableLayoutPanel
//{
// RowCount = 2,
// ColumnCount = 1,
// Dock = DockStyle.Fill,
// Margin = new Padding(0)
//};
//new_tbl.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));
//new_tbl.RowStyles.Add(new RowStyle(SizeType.AutoSize));
//new_tbl.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
//new_tbl.Controls.Add(new_radiobutton, 0, 0);
//new_tbl.Controls.Add(new_rembutton, 0, 1);
tbl_groups.RowCount = tbl_groups.RowCount + 1;
tbl_groups.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tbl_groups.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tbl_groups.Controls.Add(new_radiobutton, 0, tbl_groups.RowCount - 1);
tbl_groups.Controls.Add(new_rembutton, 1, tbl_groups.RowCount - 1);
}
一般情况下,一个Panel中一次只能勾选一个RadioButton。
现在我有一个Panel(主要是实现垂直滚动),里面有一个两列的TableLayoutPanel。通过单击 "Add row" 按钮,可以向 TLP 无限添加新行(这就是我需要面板向下滚动的原因)。
TLP 中的每一行看起来都一样:
第一列包含另一个具有一列和两行的 TLP。第一行仅包含一个 RadioButton,第二行仅包含另一个按钮。
第二列包含一个 CheckedListBox。
这么说吧,我在 TLP 中添加了 5 行。所以我有 5 个 RadioButtons。不知道为什么,但是可以一次检查所有 RadioButtons。我怎样才能避免这种情况?
这里是添加行到 TLP 的代码:
void add_newbox()
{
var new_chklistbox = new CheckedListBox{
Dock=DockStyle.Fill,
Margin=new Padding(0,0,0,3),
Location=new Point(20,0),
Size=new Size(238,94),
HorizontalScrollbar=true,
CheckOnClick=true
};
var new_radiobutton = new RadioButton{
Text="",
Dock=DockStyle.Fill,
Location=new Point(3,3),
Size=new Size(14,90),
MaximumSize=new Size(0,90)
};
new_radiobutton.Click += (sender, e) => this.focus=new_chklistbox;
var new_rembutton = new Button{
Text="-",
Dock=DockStyle.Fill,
AutoSize=true,
AutoSizeMode=AutoSizeMode.GrowAndShrink,
Margin=new Padding(0)
};
new_rembutton.Click += (sender, e) => rem_items();
var new_tbl = new TableLayoutPanel{
RowCount=2,
ColumnCount=1,
Dock=DockStyle.Fill,
Margin=new Padding(0)
};
new_tbl.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));
new_tbl.RowStyles.Add(new RowStyle(SizeType.AutoSize));
new_tbl.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
new_tbl.Controls.Add(new_radiobutton,0,0);
new_tbl.Controls.Add(new_rembutton,0,1);
tbl_groups.Controls.Add(new_tbl,0,tbl_groups.RowCount);
tbl_groups.Controls.Add(new_chklistbox,1,tbl_groups.RowCount);
}
你好,xola
使用 Radiobutton 的 GroupName 属性。
<RadioButton Content="{content}" GroupName="RadioGroupIdentifier"/>
我猜这就是你要找的东西。
编辑
没有注意到您指的是 win 表单(您可以将其写在问题中,因为标签在阅读时经常被跳过)。
但是,你应该阅读 this article from microsoft ,这里是有用的部分:
- 从 Windows 表单选项卡中拖出一个 GroupBox 或 Panel 控件 将工具箱拖到窗体上。
- 在 GroupBox 或 Panel 控件上绘制 RadioButton 控件。
一般情况下,每个 RadioButton 都默认分组在父 GroupBox 或 Panel 中。
没有其他简单的方法可以仅通过设计器来完成此操作。 您当然可以通过事件 buuuut 实现您自己的逻辑....我不建议这样做。
试试这个。它可能对你有用。
void add_newbox()
{
var new_chklistbox = new CheckedListBox{
Dock=DockStyle.Fill,
Margin=new Padding(0,0,0,3),
Location=new Point(20,0),
Size=new Size(238,94),
HorizontalScrollbar=true,
CheckOnClick=true
};
var new_radiobutton = new RadioButton{
Text="",
Dock=DockStyle.Fill,
Location=new Point(3,3),
Size=new Size(14,90),
MaximumSize=new Size(0,90)
};
//new_radiobutton.Click += (sender, e) => this.focus=new_chklistbox;
var new_rembutton = new Button{
Text="-",
Dock=DockStyle.Fill,
AutoSize=true,
AutoSizeMode=AutoSizeMode.GrowAndShrink,
Margin=new Padding(0)
};
//new_rembutton.Click += (sender, e) => rem_items();
var new_tbl = new TableLayoutPanel{
RowCount=2,
ColumnCount=1,
Dock=DockStyle.Fill,
Margin=new Padding(0)
};
var new_panel = new Panel
{
Dock = DockStyle.Fill,
AutoSize = true,
Margin = new Padding(0)
};
new_panel.Controls.Add(new_radiobutton);
new_panel.Controls.Add(new_rembutton);
new_tbl.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));
new_tbl.RowStyles.Add(new RowStyle(SizeType.AutoSize));
new_tbl.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
new_tbl.Controls.Add(new_panel, 0, 0);
要让一些单选按钮作为一个组,您应该将它们全部托管在同一个容器中。不同的 table 布局面板是不同的容器。它描述了行为。
如果出于任何原因你想保持布局不变,你需要将这些单选按钮的 AutoCheck
属性 设置为 true 并处理它们的 Click
事件以检查只需单击一个并取消选中其余的。
例子
private void Form1_Load(object sender, EventArgs e)
{
var radios = GetChildren(tableLayoutPanel1).OfType<RadioButton>();
foreach (var radio in radios)
{
radio.AutoCheck=false;
radio.Click += (obj, arg) =>
{
radio.Checked = true;
foreach(var r in radios)
if (r != radio)
r.Checked = false;
};
}
}
IEnumerable<Control> GetChildren(Control control)
{
foreach (Control c1 in control.Controls)
{
yield return c1;
foreach (Control c2 in GetChildren(c1))
yield return c2;
}
}
我对您的代码做了一些改动,并对旧代码进行了注释。请试试看。在此代码中,我在现有 TPL 控件中添加新行,而不是每次都添加新的 TLP。
void add_newbox()
{
var new_chklistbox = new CheckedListBox
{
Dock = DockStyle.Fill,
Margin = new Padding(0, 0, 0, 3),
Location = new Point(20, 0),
Size = new Size(238, 94),
HorizontalScrollbar = true,
CheckOnClick = true
};
var new_radiobutton = new RadioButton
{
Text = "",
Dock = DockStyle.Fill,
Location = new Point(3, 3),
Size = new Size(14, 90),
MaximumSize = new Size(0, 90)
};
new_radiobutton.Click += (sender, e) => this.focus = new_chklistbox;
var new_rembutton = new Button
{
Text = "-",
Dock = DockStyle.Fill,
AutoSize = true,
AutoSizeMode = AutoSizeMode.GrowAndShrink,
Margin = new Padding(0)
};
new_rembutton.Click += (sender, e) => rem_items();
//var new_tbl = new TableLayoutPanel
//{
// RowCount = 2,
// ColumnCount = 1,
// Dock = DockStyle.Fill,
// Margin = new Padding(0)
//};
//new_tbl.RowStyles.Add(new RowStyle(SizeType.Percent, 70F));
//new_tbl.RowStyles.Add(new RowStyle(SizeType.AutoSize));
//new_tbl.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
//new_tbl.Controls.Add(new_radiobutton, 0, 0);
//new_tbl.Controls.Add(new_rembutton, 0, 1);
tbl_groups.RowCount = tbl_groups.RowCount + 1;
tbl_groups.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tbl_groups.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
tbl_groups.Controls.Add(new_radiobutton, 0, tbl_groups.RowCount - 1);
tbl_groups.Controls.Add(new_rembutton, 1, tbl_groups.RowCount - 1);
}