using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
internal class WindowAutoResizer // 窗口大小自适应类
{
private readonly Form _form;
private float originalWidth;
private float originalHeight;
///
/// 初始化窗口自适应调整器
///
/// 要自适应的窗体
public WindowAutoResizer(Form form)
{
_form = form ?? throw new ArgumentNullException(nameof(form));
Initialize();
}
private void Initialize()
{
originalWidth = _form.Width;
originalHeight = _form.Height;
// 记录初始控件位置和大小
SetTag(_form);
// 注册窗口大小改变事件
_form.Resize += async (sender, e) => await OnFormResizeAsync();
}
///
/// 记录控件初始位置和大小信息
/// 递归所有控件,存储宽、高、位置等到Tag
///
/// 容器控件
private void SetTag(Control container)
{
foreach (Control control in container.Controls) // 遍历容器(cons)所有子控件。
{
control.Tag = $"{control.Width}:{control.Height}:{control.Left}:{control.Top}:{control.Font.Size}";
if (control.Controls.Count > 0)
{
SetTag(control);
}
}
}
///
/// 窗体大小改变时异步调整控件
///
private async Task OnFormResizeAsync()
{
float widthRatio = _form.Width / originalWidth;
float heightRatio = _form.Height / originalHeight;
await Task.Run(() => AdjustControls(widthRatio, heightRatio, _form));
}
///
/// 根据比例调整控件大小和位置
///
/// 宽度比例
/// 高度比例
/// 容器控件
private void AdjustControls(float widthRatio, float heightRatio, Control container)
{
if (container.InvokeRequired) // 检查是否在UI线程
{
container.Invoke(new Action(() => AdjustControls(widthRatio, heightRatio, container)));
return;
}
// 暂停控件的布局逻辑,直到所有更改完成后再一次性重新计算布局
container.SuspendLayout();
try
{
// 拷贝一份,避免实时读取时被修改造成异常
var controlsCopy = container.Controls.Cast().ToArray();
foreach (Control control in controlsCopy)
{
if (control.Tag == null) continue;
string[] tagValues = control.Tag.ToString().Split(':');
if (tagValues.Length != 5) continue;
control.Width = (int)(float.Parse(tagValues[0]) * widthRatio);
control.Height = (int)(float.Parse(tagValues[1]) * heightRatio);
control.Left = (int)(float.Parse(tagValues[2]) * widthRatio);
control.Top = (int)(float.Parse(tagValues[3]) * heightRatio);
float newFontSize = float.Parse(tagValues[4]) * heightRatio;
if (Math.Abs(control.Font.Size - newFontSize) > float.Epsilon)
{
control.Font = new Font(control.Font.Name, newFontSize, control.Font.Style);
}
// 如果当前控件有子控件,递归调整子控件
if (control.HasChildren)
{
AdjustControls(widthRatio, heightRatio, control);
}
}
}
finally
{
// 恢复控件的布局逻辑,并强制立即重新计算布局。
container.ResumeLayout(true);
}
}
///
/// 重新初始化控件位置和大小信息(当动态添加控件后调用)
///
public void RefreshTags()
{
SetTag(_form);
}
private void AddNewControl()
{
//var newButton = new Button { Text = "New Button", ... };
//this.Controls.Add(newButton);
//resizer.RefreshTags(); // 重新记录所有控件信息
}
}
}