安木生 - 自适应
type: channel
link: https://www.anmusheng.com/index.php/tag/%E8%87%AA%E9%80%82%E5%BA%94/
items: WinForm窗体及其控件自适应各种屏幕分辨率

WinForm窗体及其控件自适应各种屏幕分辨率
type: item
date: 2019-10-22T09:03:00+00:00
description: 背景我们自己编写程序的界面，会遇到各种屏幕分辨率，只有自适应才能显的美观。实际上，做到这点也很简单，就是首先记录窗体和它上面控件的初始位置和大小，当窗体改变比例时，其控件的位置和大小也按此比例变化即可。（因为窗体上控件的位置和大小是相对于自己所在的窗体的。）使用方法声明自适应辅助类实例为窗体添加Load事件，并在其方法Form\_Load中，调用自适应辅助类方法，记录窗体和其控件初始位置和大小为窗体添加SizeChanged事件，并在其方法Form\_SizeChanged中，调用自适应辅助类的自适应方法，完成自适应完整代码自适应窗体public partial class Form1 : Form { // 声明自适应辅助类实例 AutoSizeFormHelper asf = new AutoSizeFormHelper(); public Form1() { InitializeComponent(); } // 为窗体添加Load事件，并在其方法Form1_Load中，调用自适应辅助类方法，记录窗体和其控件的初始位置和大小 private void Form1_Load(object sender, EventArgs e) { asf.ControlInitializeSize(this); } // 为窗体添加SizeChanged事件，并在其方法Form1_SizeChanged中，调用自适应辅助类的自适应方法，完成自适应 private void Form1_SizeChanged(object sender, EventArgs e) { asf.ControlAutoSize(this); } }自适应辅助类/// /// 自适应窗体辅助类 /// public class AutoSizeFormHelper { // 窗体和其控件的初始位置和大小。 public class ControlRect { public int Left; public int Top; public int Width; public int Height; public ControlRect(int l, int t, int w, int h) { Left = l; Top = t; Width = w; Height = h; } } // 当前控件的位置和大小 public ConditionalWeakTable<Control, ControlRect> oldControls = new ConditionalWeakTable<Control, ControlRect>(); // 当前的窗体位置和大小 public ControlRect formRect; // 记录窗体和其控件的初始位置和大小 public void ControlInitializeSize(Form mForm) { // 窗体自身位置 this.formRect = new ControlRect(mForm.Left, mForm.Top, mForm.Width, mForm.Height); foreach (Control c in mForm.Controls) { ControlRect controlRect = new ControlRect(c.Left, c.Top, c.Width, c.Height); oldControls.Add(c, controlRect); } //记录完控件的初始位置和大小后，最大化 mForm.WindowState = System.Windows.Forms.FormWindowState.Maximized; } // 控件自适应大小, public void ControlAutoSize(Form mForm) { // 缩放比例 float wScale = (float)mForm.Width / (float)formRect.Width; float hScale = (float)mForm.Height / (float)formRect.Height; ControlRect data; foreach (Control c in mForm.Controls) { if (oldControls.TryGetValue(c, out data)) { c.Left = (int)((data.Left) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体，所以只需成比例 c.Top = (int)((data.Top) * hScale); c.Width = (int)(data.Width * wScale); c.Hei…