Files
huabe-sitondao/SLC1-N/WindowAutoResizer.cs
2025-11-14 16:12:32 +08:00

139 lines
4.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
/// <summary>
/// 初始化窗口自适应调整器
/// </summary>
/// <param name="form">要自适应的窗体</param>
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();
}
/// <summary>
/// 记录控件初始位置和大小信息
/// 递归所有控件存储宽、高、位置等到Tag
/// </summary>
/// <param name="container">容器控件</param>
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);
}
}
}
/// <summary>
/// 窗体大小改变时异步调整控件
/// </summary>
private async Task OnFormResizeAsync()
{
float widthRatio = _form.Width / originalWidth;
float heightRatio = _form.Height / originalHeight;
await Task.Run(() => AdjustControls(widthRatio, heightRatio, _form));
}
/// <summary>
/// 根据比例调整控件大小和位置
/// </summary>
/// <param name="widthRatio">宽度比例</param>
/// <param name="heightRatio">高度比例</param>
/// <param name="container">容器控件</param>
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<Control>().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);
}
}
/// <summary>
/// 重新初始化控件位置和大小信息(当动态添加控件后调用)
/// </summary>
public void RefreshTags()
{
SetTag(_form);
}
private void AddNewControl()
{
//var newButton = new Button { Text = "New Button", ... };
//this.Controls.Add(newButton);
//resizer.RefreshTags(); // 重新记录所有控件信息
}
}
}