当窗口最大化时或者自己拉拽变化大小时,我们会看到窗口的控件不会随着窗口变化而变化。如果想等比例变化,其实只需要根据窗口变化比例,来等比例变化窗口控件的长,宽和其位置坐标及字体大小即可。所以在窗口InitializeComponent()初始化控件后,用全局变量记录下它的原始长和宽,然后再根据它的变化长和宽来计算比例,同样放大和缩小控件就行。我们知道,窗口控件都有一个给用户自定义的数据的属性Tag,我们就把控件变化前的长,宽,坐标和字体大小记录在Tag中,以便对变化后的尺寸时行缩放。代码如下:
public partial class Form1 : Form
{
//等比例缩放的原始点
private float X;
private float Y;
#region 所有控件等比例缩放
private void setTag(Control cons)
{
foreach (Control con in cons.Controls)
{
con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
if (con.Controls.Count > 0)
setTag(con);
}
}
private void setControls(float newx, float newy, Control cons)
{
foreach (Control con in cons.Controls)
{
string[] mytag = con.Tag.ToString().Split(':');
float a = Convert.ToSingle(mytag[0]) * newx;
con.Width = (int)a;
a = Convert.ToSingle(mytag[1]) * newy;
con.Height = (int)(a);
a = Convert.ToSingle(mytag[2]) * newx;
con.Left = (int)(a);
a = Convert.ToSingle(mytag[3]) * newy;
con.Top = (int)(a);
Single currentSize = Convert.ToSingle(mytag[4]) * Math.Min(newx, newy);
con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
if (con.Controls.Count > 0)
{
setControls(newx, newy, con);
}
}
}
void Form_Resize(object sender, EventArgs e)
{
float newx = (this.Width) / X;
float newy = this.Height / Y;
setControls(newx, newy, this);
}
#endregion
public Form1()
{
InitializeComponent();
X = this.Width;
Y = this.Height;
//在窗体加载时候 解决闪烁问题
//将图像绘制到缓冲区 减少闪烁
this.DoubleBuffered = true;//设置本窗体
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
}
private void Form1_Load(object sender, EventArgs e)
{
//按键等比例缩放,注册到窗口Resize事件中
this.Resize += new EventHandler(Form_Resize);
setTag(this);
//在MDI时用
//Form_Resize(new object(), new EventArgs());
}
}
为了阅读程序的连续性,我把窗口默认的Form1类也写到上述代码中了,大家可以自行选择使用代码。