visual - validar radio button c#




¿Por qué mi GroupBox creado dinámicamente coloca sus RadioButtons demasiado a la derecha en usos posteriores? (2)

Estoy agregando varios controles creados dinámicamente a un panel, según lo que el usuario seleccione. Si un Groupbox, con RadioButtons asociados, es el primer control, se ve bien:

... pero si se trata de algo más que eso, los botones de radio asociados parecen estar alineados a la derecha en lugar de alineados a la izquierda, como se ve arriba, y el cuadro de grupo es demasiado ancho, para arrancar.

Aquí está el código pertinente (se llama a RepaintMockupPanel () cuando el usuario opta por ver cómo se ve su maqueta en cualquier momento, y getGroupBox () es el método que llama que debería ser donde reside el problema, pero no puedo verlo .

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;
}

¿Por qué no usar TableLayoutPanel o FlowLayoutPanel para colocar automáticamente los controles, puede insertar con relleno dock el GroupBox? Entonces solo necesita agregar los controles a ... LayoutPanel y posicionarse automáticamente. Tiene varias opciones para controlar las filas y / o columnas del TableLayoutPanel Y como otros controles para controlar el flujo en el FlowLayoutPanel Aquí un ejemplo usando el panel de diseño, coloque un Top acoplado con un botón y un Fill insertado TabControl vacío, y pruebe este código

private void button1_Click(object sender, EventArgs e)
    {
        for (int t = 0; t < 4;t++ )
            tabControl1.TabPages.Add(CreateTabPage(t));
    }

    private TabPage CreateTabPage(int t)
    {

        TabPage result = new TabPage()
        {
            Text=string.Format("TabPage {0}",t)
        };
        FlowLayoutPanel flp = new FlowLayoutPanel()
        {
            Dock = DockStyle.Fill,
            AutoScroll = true,
        };
        for (int i = 0; i < 10; i++)
        {
            flp.Controls.Add(CreateGroupBox(i));
        }
        result.Controls.Add(flp);
        return result;
    }

    private Control CreateGroupBox(int i)
    {
        GroupBox result = new GroupBox()
        {
            Text = string.Format("GroupBox {0}", i),
            Width = 150,
            Height = 100
        };
        FlowLayoutPanel flp = new FlowLayoutPanel()
        {
            Dock = DockStyle.Fill,
            WrapContents = false,
            AutoScroll = true,
            FlowDirection=FlowDirection.TopDown
        };
        CreateRadios(flp, i);
        result.Controls.Add(flp);
        return result;
    }

    private void CreateRadios(FlowLayoutPanel flp, int i)
    {
        for (int c = 0; c < 10; c++) {
            flp.Controls.Add(new RadioButton()
            {
                Text = string.Format("RadioButton {0} in {1}", c, i)
            });
        }
    }

El método getGroupBox () es INDEED donde reside el problema.

Como contenedor, GroupBox tiene su propio lienzo sobre el que se dibujan sus controles secundarios, por lo que cuando crea un control con un valor X de 5, significa que es 5 desde la izquierda del GroupBox, NO desde la izquierda del formulario. Su valor absoluto en el formulario sería su propio valor X (por ejemplo, en este caso 5) más el valor X de GroupBox (que asumiremos que tiene un valor izquierdo de 25) para una posición absoluta de 30 desde la izquierda.

Esta es la razón por la cual su ejemplo muestra los botones de radio presionados hasta ahora: si examina la distancia entre el borde izquierdo de los RadioButtons en relación con el borde izquierdo de su GroupBox que lo contiene, debería estar a la misma distancia que el borde izquierdo del GroupBox desde el borde izquierdo de su contenedor.