关于c#:为什么仅将第一个单选按钮添加到GroupBox?

Why is only the first RadioButton being added to the GroupBox?

我试图动态创建Windows控件并将其添加到面板中。对于"按钮和复选框",它工作正常;但是,我在GroupBox中遇到了RadioButtons的问题。

将创建第一个RadioButton元素并将其添加到GroupBox的预期位置,但是一些可疑的元素虽然表面上已创建(逐步浏览代码使得情况确实如此),但它们是不可见的。

我认为,如果将后续的RadioButton放置在先前的RadioButton上,那么最后一个将是看到的那个。看起来是这样的:

enter image description here

每个以?分隔的val应该是单选按钮的文本值,但只能显示一个。我是否需要为后续的RadioButton明确提供Location val,还是为什么会失败?

这是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private GroupBox getGroupBox(string currentSettings, int curLeftVal)
{
    //"apple~orange~peach~True (must look for"enclose group in a black box" as the last val (ignore for the quick-and-dirty mockup, though))
    List<string> grpbxVals = new List<string>(currentSettings.Split('~'));
    GroupBox gb = new GroupBox();
    gb.Height = 60;
    gb.Location = new Point(curLeftVal, PANEL_TOP_LOC);
    RadioButton radbtn = null;
    //"-1" because we're ignoring the final bool ("enclose in black box")
    for (int i = 0; i < grpbxVals.Count-1; i++)
    {
        radbtn = new RadioButton();
        radbtn.Text = grpbxVals[i];
        gb.Controls.Add(radbtn);
    }
    return gb;
}

更新

皮埃尔(Pierre)在下面的答案中提出的想法似乎很明智,但仍然不完全符合医生的要求:

enter image description here

更新2

效果很好(修改Pierre的代码):

1
2
3
4
5
6
7
8
9
10
IList<string> grpbxVals = new List<string>(currentSettings.Split('~'));
GroupBox gb = new GroupBox { Height = 60, Location = new Point(curLeftVal, 0) };

int radButtonPosition = 0;
for (int i = 0; i < grpbxVals.Count() - 1; i++)
{
    gb.Controls.Add(new RadioButton { Text = grpbxVals[i], Location = new Point(curLeftVal, radButtonPosition) });
    radButtonPosition += new RadioButton().Height - 4; // the"-4" is a kludge
}
return gb;

给我:

enter image description here


所有项目均为位置0,0
尝试这个

1
2
3
4
5
6
7
8
9
10
int y=20;
for (int i = 0; i < grpbxVals.Count-1; i++)
    {
        radbtn = new RadioButton();
        radbtn.Text = grpbxVals[i];
        radbtn.Location=new System.Drawing.Point(6, y);
        y+=radbtn.Height;
        gb.Controls.Add(radbtn);
        radbtn = null;
    }

也可以将FlowLayoutPanel插入GroupBox内,然后将RadioButton添加到FlowLayoutPanel中,以自动放置组件


如果设置了断点,您将看到您的分组框包含所有单选按钮。它们的位置确实完全相同,因此将它们显示在另一个之上。问题不在于将它们全部添加到组框,而是将它们全部显示。

为此,只需增加它们在每个添加操作上的位置即可显示所有位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private GroupBox getGroupBox(string currentSettings, int curLeftVal)
{
    //"apple~orange~peach~True (must look for"enclose group in a black box" as the last val (ignore for the quick-and-dirty mockup, though))
    List<string> grpbxVals = new List<string>(currentSettings.Split('~'));
    GroupBox gb = new GroupBox();
    gb.Height = 60;
    gb.Location = new Point(curLeftVal, PANEL_TOP_LOC);
    RadioButton radbtn = null;
    //"-1" because we're ignoring the final bool ("enclose in black box")
    int radButtonPosition = PANEL_TOP_LOC;
    for (int i = 0; i < grpbxVals.Count - 1; i++)
    {
        radbtn = new RadioButton();
        radbtn.Text = grpbxVals[i];
        radbtn.Location = new Point(curLeftVal, radButtonPosition );
        radButtonPosition += radbtn.Height;
        gb.Controls.Add(radbtn);

    }
    return gb;
}

我正在定义一个名为radButtonPosition的变量,并将其初始化到组框的位置。然后,我根据它设置单选按钮的位置,然后每次添加一个单选按钮时,就将radButtonPosition增加一个单选按钮的高度。

这也是一些重构版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private GroupBox CreateGroupboxWithRadiobuttons(string currentSettings, int curLeftVal)
{
    IList<string> grpbxVals = new List<string>(currentSettings.Split('~'));
    GroupBox gb = new GroupBox { Height = 60, Location = new Point(curLeftVal, PANEL_TOP_LOC) };

    int radButtonPosition = PANEL_TOP_LOC;
    for (int i = 0; i < grpbxVals.Count() - 1; i++)
    {
        gb.Controls.Add(new RadioButton {Text = grpbxVals[i], Location = new Point(curLeftVal, radButtonPosition)});
        radButtonPosition += new RadioButton().Height;
    }

    return gb;
}

当然,要遵循SRP,需要做很多方法提取工作,但这只是一个开始。