7

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.

2 Answers2

19

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(); 
pescolino
  • 3,086
  • 2
  • 14
  • 24
  • 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. – Lyndon Broz Tonelete Oct 05 '13 at 02:43
  • @LyndonBrozTonelete: I added some code and also some comments on your code. – pescolino Oct 05 '13 at 03:37
  • i wonder if i can put dynamic radiobutton below each of my pictureboxes.. is it possible too? – Lyndon Broz Tonelete Oct 05 '13 at 08:50
  • @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. – pescolino Oct 05 '13 at 16:39
0

You can always drop a control on your form, do what you want to do then look at the designer generated code to see how the designer does it (in the "Designer.cs" file). Behind the scenes it is loading all controls and setting all properties via code.

That being said.

Keep in mind that once you put your picturebox inside the groupbox all location coordinate are in relation to the groupbox. So "0,0" is the upper-left corner of the groupbox, not the form.

To anchor your picturebox use the following code (this is just a straight copy-paste from my designer generated code, so you can clean it up a bit):

this.PresPB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
        | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));

To dock your picture box (so it fills the entire containing control):

this.PresPB.Dock = System.Windows.Forms.DockStyle.Fill;

You also need to change this line:

this.Controls.Add(PresPB);

to this:

PresGB.Controls.Add(PresPB);
Zippit
  • 1,673
  • 1
  • 11
  • 11
  • 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 Oct 05 '13 at 01:53