C#快速自适应布局

发布时间 2023-09-02 08:16:52作者: 阿小ZY

网上找的  :https://note.youdao.com/s/AYDJgzBk

视频:C#5分钟winform快速自适应布局_哔哩哔哩_bilibili

实现方法:会将form装进Panel里面对控件进行自动计算

在项目中添加AutoWindowsSize.cs类

优势:不需要再Form1中添加任何布局,直接将类复制到项目中,在Form1代码中调用即可,页面大小会自动计算,修改方便,速度快

缺点:页面如果是背景图片,页面特别快的时候,页面会有闪烁的情况

  如果Form1 中有背景图片,会直接拿显示成纯图的背景,原因在AutoAdaptWindowsSize类中会创建一个panel,panel背景颜色会自动设置,而panel的纯色背景会覆盖掉Form1 的背景,本质上是panel的背景。所以给Panel设置背景图片或将panel背景图片修改为Transparent

Win_Panel1.BackColor = Color.Transparent;

其次:因为修改窗口需要对界面重新绘制,在拖动窗口时会出现比较严重的闪屏现象,需要在Form1中任意位置添加如下代码

protected override CreateParams CreateParams()
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }

 

 
  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 //using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 
 10 using System.Drawing.Drawing2D;
 11 //using System.Threading.Tasks;
 12 
 13 
 14 namespace AutoWindowsSize
 15 {
 16     class AutoAdaptWindowsSize                       //窗口缩放对象
 17     {
 18         double formOriginalWidth;//窗体高度原始宽度
 19         double formOriginalHeight;//窗体原始
 20         double scaleX;//水平缩放比例
 21         double scaleY;//垂直缩放比例
 22 
 23         Dictionary<string, string> ControlsInfo = new Dictionary<string, string>();//控件中心Left,Top,控件Width,控件Height,控件字体Size
 24 
 25         private Form _form;
 26         Panel Win_Panel1 = new Panel();
 27 
 28         public AutoAdaptWindowsSize(Form form)
 29         {
 30             _form = form;
 31 
 32             //代码生成一个容器panel1,添加至窗体
 33             _form.Controls.Add(Win_Panel1);
 34             Win_Panel1.BorderStyle = BorderStyle.None;    //容器border样式
 35             Win_Panel1.Dock = DockStyle.Fill;                    //设置填充,下面添加控件至容器完成后,容器会填充窗口
 36             Win_Panel1.BackColor = Color.Transparent;
 37 
 38 
 39             //将窗体所有控件添加至panel1
 40             while (_form.Controls[0].Name.Trim() != "")
 41             {
 42                 foreach (Control item in _form.Controls)
 43                 {
 44 
 45                     if (item.Name.Trim() != "" && item.Name.Trim() != Win_Panel1.Name.Trim())
 46                     {
 47                         Win_Panel1.Controls.Add(item);
 48                     }
 49                 }
 50             }
 51 
 52             //保存窗体和控件初始大小
 53             InitControlsInfo(Win_Panel1);
 54         }
 55         /// <summary>
 56         /// 
 57         /// </summary>
 58         /// <param name="ctrlContainer">panel 控件</param>
 59         public void InitControlsInfo(Control ctrlContainer)
 60         {
 61             if (ctrlContainer.Parent == _form)//获取窗体的高度和宽度
 62             {
 63                 formOriginalWidth = Convert.ToDouble(ctrlContainer.Width);
 64                 formOriginalHeight = Convert.ToDouble(ctrlContainer.Height);
 65             }
 66             foreach (Control item in ctrlContainer.Controls)
 67             {
 68                 if (item.Name.Trim() != "")
 69                 {
 70                     //添加信息:键值:控件名,内容:据左边距离,距顶部距离,控件宽度,控件高度,控件字体。
 71                     ControlsInfo.Add(item.Name, (item.Left + item.Width / 2) + "," + (item.Top + item.Height / 2) + "," + item.Width + "," + item.Height + "," + item.Font.Size);
 72                 }
 73                 if ((item as UserControl) == null && item.Controls.Count > 0)
 74                 {
 75                     InitControlsInfo(item);
 76                 }
 77             }
 78 
 79         }
 80 
 81 
 82         public void FormSizeChanged()
 83         {
 84             try
 85             {
 86                 if (ControlsInfo.Count > 0)//如果字典中有数据,即窗体改变
 87                 {
 88                     ControlsZoomScale(Win_Panel1);//表示pannel控件
 89                     ControlsChange(Win_Panel1);
 90                 }
 91             }
 92             catch { }
 93         }
 94         private void ControlsZoomScale(Control ctrlContainer)
 95         {
 96             scaleX = (Convert.ToDouble(ctrlContainer.Width) / formOriginalWidth);
 97             scaleY = (Convert.ToDouble(ctrlContainer.Height) / formOriginalHeight);
 98         }
 99 
100         /// <summary>
101         /// 改变控件大小
102         /// </summary>
103         /// <param name="ctrlContainer"></param>
104         private void ControlsChange(Control ctrlContainer)
105         {
106             double[] pos = new double[5];//pos数组保存当前控件中心Left,Top,控件Width,控件Height,控件字体Size
107             foreach (Control item in ctrlContainer.Controls)//遍历控件
108             {
109                 if (item.Name.Trim() != "")//如果控件名不是空,则执行
110                 {
111                     if ((item as UserControl) == null && item.Controls.Count > 0)//如果不是自定义控件
112                     {
113                         ControlsChange(item);//循环执行
114                     }
115                     string[] strs = ControlsInfo[item.Name].Split(',');//从字典中查出的数据,以‘,’分割成字符串组
116 
117                     for (int i = 0; i < 5; i++)
118                     {
119                         pos[i] = Convert.ToDouble(strs[i]);//添加到临时数组
120                     }
121                     double itemWidth = pos[2] * scaleX;     //计算控件宽度,double类型
122                     double itemHeight = pos[3] * scaleY;    //计算控件高度
123                     item.Left = Convert.ToInt32(pos[0] * scaleX - itemWidth / 2);//计算控件距离左边距离
124                     item.Top = Convert.ToInt32(pos[1] * scaleY - itemHeight / 2);//计算控件距离顶部距离
125                     item.Width = Convert.ToInt32(itemWidth);//控件宽度,int类型
126                     item.Height = Convert.ToInt32(itemHeight);//控件高度
127                     if (float.Parse((pos[4] * Math.Min(scaleX, scaleY)).ToString()) != 0)         //缩放字体大小不能为0
128                     { item.Font = new Font(item.Font.Name, float.Parse((pos[4] * Math.Min(scaleX, scaleY)).ToString())); }  //字体
129 
130                 }
131             }
132 
133         }
134 
135 
136     }
137 }

1.引入using AutoWindowsSize;

2.在Form1类中设置全局变量AutoAdaptWindowsSize AutoSize;

3.在添加如下代码

  private void Form1_Load(object sender, EventArgs e)
        {
            AutoSize = new AutoAdaptWindowsSize(this);
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            AutoSize.FormSizeChanged();
        }