I am adding various dynamically created controls to a panel, based on what the user selects. If a Groupbox, with associated RadioButtons, is the first control, it looks fine:
...but if it's anything other than that, the associated radio buttons seem right-aligned instead of left-aligned, as seen above, and the groupbox is too wide, to boot.
Here is the pertinent code (RepaintMockupPanel() is called when the user opts to see what his mockup looks like at any time, and getGroupBox() is the method it calls that should be where the problem lies, but I can't see it.
private void RepaintMockupPanel(Control padre)
{
const string BTN = "BUTTON";
const string CKBX = "CHECKBOX";
const string EDTTXT = "EDITTEXT";
const string RADGRP = "RADIOGROUP";
const string SPNR = "SPINNER";
const string TXTVU = "TEXTVIEW";
const int LEFT_STARTING_POINT = 4;
const int STANDARD_PADDING = 4;
int currentLeft = LEFT_STARTING_POINT;
string currentSel;
string currentSettings;
ComboBox cmbx;
Label lbl;
try
{
TabPage tp = padre as TabPage;
string panelName = tp.Name.Replace("tabPage", "panel");
Panel p = tp.Controls[panelName] as Panel;
p.Controls.Clear();
for (int i = 0; i < p.Controls.Count; i++)
{
p.Controls[i].Dispose();
}
//cmbxRow0Element0 and lblRow0Element0 to cmbxRow11Element5 and lblRow11Element5
int rowNum = getRowNum(panelName);
for (int i = 0; i < WIDGETS_PER_TABPAGE; i++)
{
cmbx = tp.Controls[string.Format("cmbxRow{0}Element{1}", rowNum, i)] as ComboBox;
lbl = tp.Controls[string.Format("lblRow{0}Element{1}", rowNum, i)] as Label;
if (cmbx.SelectedIndex < 0) continue;
currentSel = cmbx.SelectedItem.ToString().ToUpper();
currentSettings = lbl.Text;
// Possible vals (Android on left, Windows equivalents on the right:
//Button ""
//CheckBox ""
//EditText TextBox
//RadioGroup GroupBox (w. RadioButtons nested within)
//Spinner ComboBox
//TextView Label
if ((currentSel.Length > 0) && (currentSettings.Length > 0))
{
if (currentSel.Equals(BTN))
{
Button btn = getButton(currentSettings, currentLeft);
p.Controls.Add(btn);
currentLeft += btn.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(CKBX))
{
CheckBox ckbx = getCheckBox(currentSettings, currentLeft);
p.Controls.Add(ckbx);
currentLeft += ckbx.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(EDTTXT))
{
TextBox txtbx = getTextBox(currentSettings, currentLeft);
p.Controls.Add(txtbx);
currentLeft += txtbx.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(RADGRP))
{
GroupBox grpbx = getGroupBox(currentSettings, currentLeft);
p.Controls.Add(grpbx);
currentLeft += grpbx.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(SPNR))
{
ComboBox cmbxDyn = getComboBox(currentSettings, currentLeft);
p.Controls.Add(cmbxDyn);
currentLeft += cmbxDyn.Width + STANDARD_PADDING;
}
else if (currentSel.Equals(TXTVU))
{
Label lblDyn = getLabel(currentSettings, currentLeft);
p.Controls.Add(lblDyn);
currentLeft += lblDyn.Width + STANDARD_PADDING;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
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))
// Adapted from Pierre's answer at http://stackoverflow.com/questions/23944419/why-is-only-the-first-radiobutton-being-added-to-the-groupbox
IList<string> grpbxVals = new List<string>(currentSettings.Split('~'));
GroupBox gb = new GroupBox { Height = 60, Location = new Point(curLeftVal, 0) };
gb.AutoSize = true;
int radButtonYVal = 0;
for (int i = 0; i < grpbxVals.Count() - 1; i++)
{
//gb.Controls.Add(new RadioButton { Text = grpbxVals[i], Location = new Point(curLeftVal, radButtonPosition) });
gb.Controls.Add(new RadioButton { Text = grpbxVals[i], Location = new Point(gb.Location.X+2, radButtonYVal) });
radButtonYVal += new RadioButton().Height;
}
return gb;
}
The getGroupBox() method is INDEED where the issue lies.
As a Container, GroupBox has its own canvas upon which its child controls are drawn, so when you create a control with an X value of 5, it means it's 5 from the left of the GroupBox, NOT from the left of the form. It's absolute value on the form would be it's own X value (say in this case 5) plus the X value of the GroupBox (which we'll assume has a Left value of 25) for an absolute positon of being 30 from the Left.
This is why your example shows the radio buttons pushed over so far: if you examine the distance between the left edge of the RadioButtons in relation to the left edge of their containing GroupBox, it should be about the same distance as the left edge of the GroupBox from the left edge of ITS container.