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 ,这里是有用的部分:

  1. 从 Windows 表单选项卡中拖出一个 GroupBox 或 Panel 控件 将工具箱拖到窗体上。
  2. 在 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);
    }