Align dynamically added controls horizontally and vertically within a control in c# winforms

25,810

Maybe the FlowLayoutPanel control already does what you are trying to do. Just create your picture boxes and add them to a FlowLayoutPanel instead of a GroupBox.

FlowLayoutPanel automatically arranges controls in rows and/or columns depending on the value of its FlowDirection property. Set myFlowLayoutPanel.FlowDirection = FlowDirection.TopDown to get a vertical arranged list.

If you don't want multiple rows or columns set the WrapContents property to false. You can also set the AutoScroll property to true to automatically get scrollbars if the controls don't fit.

If you prefer to have the border of a GroupBox you can still put the FlowLayoutPanel into a GroupBox.

To adjust the space between the picture boxes you can use the Margin property.

This gives you a lot of control over the layout and you don't need to calculate the control positions. Also, if the size of the FlowLayoutPanel changes everything is rearranged automatically.

UPDATE:

I have a few comments on your code:

  1. The curly braces make this look like the syntax of an object initializer - but it isn't.

    GroupBox PresGB = new GroupBox(); // this line ends with a semicolon
    {
        // therefore this is just a block of code not related to new GroupBox()
    };
    

    You should remove the curly braces.

  2. The creation of the group box is inside the loop. I doubt that you want a new group box for each picture box. This is the reason why you only see a single picture. Each new group box hides all the previous ones.

  3. You add the picture boxes to the form instead of the group box.

  4. You use "cryptic" names. PresGB and PresPB are very likely to be swapped accidentally. Abbreviations are usually a bad choice for names.

  5. You don't need to call SendToBack or BringToFront since you don't want the controls to overlap anyway.

  6. I don't think GroupBox is a good choice. Of course you can make it bigger if the number of pictures increases but you are limited by the screen and you don't get scollbars if the picture boxes don't fit. Use a FlowLayoutPanel. It has all the "magic" that you are looking for.

Replace your for loop with this piece of code:

var panel = new FlowLayoutPanel();
panel.SuspendLayout(); // don't calculate the layout before all picture boxes are added
panel.Size = new Size(491, 152);
panel.Location = new Point(12, 12);
panel.BorderStyle = BorderStyle.Fixed3D;
panel.FlowDirection = FlowDirection.LeftToRight;
panel.AutoScroll = true; // automatically add scrollbars if needed
panel.WrapContents = false; // all picture boxes in a single row
this.Controls.Add(panel);

for (int i = 0; i < PresCount; ++i)
{
    var pictureBox = new PictureBox();
    // the location is calculated by the FlowLayoutPanel
    pictureBox.Size = new Size(75, 75);
    pictureBox.BorderStyle = BorderStyle.FixedSingle;
    pictureBox.ImageLocation = "imgPath";
    panel.Controls.Add(pictureBox);
}

panel.ResumeLayout(); 
Share:
25,810
Lyndon Broz Tonelete
Author by

Lyndon Broz Tonelete

Updated on October 05, 2020

Comments

  • Lyndon Broz Tonelete
    Lyndon Broz Tonelete over 3 years

    I have this program that dynamically adds pictureboxes referring to the number of president in the database. How do i put them inside the groupbox and align the pictureboxes inside the groupbox? And the groupbox should stretch if the pictureboxes are many.

    I have this codes now :

        private void Form1_Load(object sender, EventArgs e)
        {
            conn.Open();
    
            try
            {
                cmd = new SqlCommand("SELECT COUNT(Position) FROM TableVote WHERE Position='" + "President" + "'", conn);
                Int32 PresCount = (Int32)cmd.ExecuteScalar();
    
                TxtPresCount.Text = PresCount.ToString();
    
                for (int i = 0; i < PresCount; ++i)
                {
                    GroupBox PresGB = new GroupBox();
                    {
                        PresGB.Size = new Size(491, 152);
                        PresGB.Location = new Point(12, 12);
                        PresGB.Text = "President";
                        this.Controls.Add(PresGB);
                        PresGB.SendToBack();
    
                        PictureBox PresPB = new PictureBox();
                        PresPB.Location = new Point(80 + (150 * i) + 20, 50);
                        PresPB.Size = new Size(75, 75);
                        PresPB.BorderStyle = BorderStyle.Fixed3D;
                        PresPB.ImageLocation = "imgPath";
                        this.Controls.Add(PresPB);
                        PresPB.BringToFront();
                    };
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                conn.Close();
            }
        }
    

    I would want the pictureboxes to be inside the groupbox and align it inside.

  • Lyndon Broz Tonelete
    Lyndon Broz Tonelete over 10 years
    thanks, but i still need the pictureboxes to be aligned inside. example if my PresCount is equal to 4, then it'll dynamically create pictureboxes inside the groupbox. all it does is it centers/fills the groupbox. the other pictureboxes cant be seen.
  • Lyndon Broz Tonelete
    Lyndon Broz Tonelete over 10 years
    can you give a sample code referring to my codes above? because its so complicated. I don't understand why my pictureboxes stays at one location only.
  • pescolino
    pescolino over 10 years
    @LyndonBrozTonelete: I added some code and also some comments on your code.
  • Lyndon Broz Tonelete
    Lyndon Broz Tonelete over 10 years
    i wonder if i can put dynamic radiobutton below each of my pictureboxes.. is it possible too?
  • pescolino
    pescolino over 10 years
    @LyndonBrozTonelete: The RadioButton control has an Image property that you can use instead of the picture boxes. The CheckAlign and ImageAlign properties give you control over the layout.