Positioning Controls in the .Net GroupBox

11.2k views Asked by At

Normally, I write forms that are resizeable (gracefully) using the method below.

using System.Drawing;
using System.Windows.Forms;
namespace silly
{
    public class Form1 : Form
    {
        private GroupBox g;
        private Button b1, b2;
        public Form1()
        {
            Init();
        }
        private void Init()
        {
            //create and add controls.
            this.Controls.Add(g = new GroupBox());
            g.Controls.AddRange(new Control[] { 
                    b1 = new Button(),
                    b2 = new Button()});


            g.Text = "group";
            b1.Text = "b1";
            b2.Text = "b2!";


            b1.AutoSize = b2.AutoSize = true;


            g.Resize += new System.EventHandler(g_Resize);

        }

        private void g_Resize(object sender, System.EventArgs e)
        {
            b1.Size = b2.Size = new Size(g.ClientSize.Width, g.ClientSize.Height/2);
            b1.Location = Point.Empty;
            b2.Location = new Point(b1.Left, b1.Bottom);
        }
        protected override void OnResize(System.EventArgs e)
        {
            g.Size = this.ClientSize;
            g.Location = Point.Empty;
        }
    }
}

However, you will quickly notice, that the g.ClientSize property doesn't work like the Form.ClientSize property. What I have been doing is adding a Point with the values:

private readonly static Point grp_zero = new Point(10, 20);

to help properly place components. Using this value, I can refactor the g_Resize method with:

b1.Size = b2.Size = new Size(g.ClientSize.Width - grp_zero.X * 2, 
    g.ClientSize.Height/2 - grp_zero.X - grp_zero.Y);
b1.Location = grp_zero;
b2.Location = new Point(b1.Left, b1.Bottom);

with fairly good results. However, if at the end of Init();, the following code is found:

            g.Font = new Font(g.Font.FontFamily, 28);

or something like it, grp_zero deserves to be resized.

Question

Is there a good workaround against this madness? What do you do?

I tried Dock and Anchor, but I can't seem to get them to make the buttons fill up the GroupBox client area. The effect I'm after here is for each button to fill his half of the client area.

Thanks in advance.

2

There are 2 answers

1
Justin On BEST ANSWER

I tried Dock and Anchor, but I can't seem to get them to make the buttons fill up the GroupBox client area. The effect I'm after here is for each button to fill his half of the client area.

  1. Add a TableLayoutPanel to the GroupBox
    1. Set its Dock property to Fill
    2. Set its RowCount = 2 and ColumnCount = 1
    3. Set the RowStyles to 50% fill for each row. Done by default in the designer.
  2. Add your two buttons to the TableLayoutPanel
    1. Set their Dock properties to Fill
  3. Done!

I also suggest giving the designer another chance - it really is very good!

0
Justin On

If you still want to use manual layout code, use the DisplayRectangle property instead of ClientRectangle. I prefer the Layout event over Resize, too.

private void g_Layout(object sender, System.LayoutEventArgs e)
{
    b1.Size = b2.Size = new Size(g.DisplayRectangle.Width, 
                                 g.DisplayRectangle.Height/2 - 1);

    b1.Location = new Point(g.DisplayRectangle.Left, 
                            g.DisplayRectangle.Top);

    b2.Location = new Point(g.DisplayRectangle.Left, 
                           g.DisplayRectangle.Top + g.DisplayRectangle.Height/2);
}

Note, however, that the documentation states:

This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.