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.
I tried
Dock
andAnchor
, but I can't seem to get them to make the buttons fill up theGroupBox
client area. The effect I'm after here is for each button to fill his half of the client area.
- Add a
TableLayoutPanel
to theGroupBox
- Set its
Dock
property toFill
- Set its
RowCount = 2
andColumnCount = 1
- Set the
RowStyles
to 50% fill for each row. Done by default in the designer.
- Set its
- Add your two buttons to the
TableLayoutPanel
- Set their
Dock
properties toFill
- Set their
- Done!
I also suggest giving the designer another chance - it really is very good!
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.
精彩评论