记录|C# winform布局学习

目录

  • 前言
  • 一、自适应布局
    • [Step1. 添加AutoAdaptWindowsSize类](#Step1. 添加AutoAdaptWindowsSize类)
    • [Step2. Form中引用](#Step2. Form中引用)
    • [Step3. 创建SizeChanged事件函数](#Step3. 创建SizeChanged事件函数)
    • [Step4. 在Fram.Disiger中添加](#Step4. 在Fram.Disiger中添加)
  • 更新时间

前言

参考视频:
C#5分钟winform快速自适应布局

参考文章:

其他参考:

写这篇文章,主要是我发现自己的界面太丑了,我受不了。而且项目运行后,winform窗口是窗口,放大后又是另一种样子,丑到家了。


一、自适应布局

以下内容的原版在这:C#快速自适应布局

下面的代码是根据我实际写的界面进行更改了的。

Step1. 添加AutoAdaptWindowsSize类

  • 做法:将Form装入Panel容器中。在项目中添加AutoAdaptWindowsSize.cs类。代码见下图【直接复制类中内容即可,添加的类名重命名为AutoAdaptWindowsSize.cs】
  • 优点:不用在Form中添加任何布局,直接将类复制到项目中,在Form代码中调用即可,页面大小会自动计算,修改方便,速度块。
  • 缺点:Form中的背景图片会直接显示成纯图的背景。【AutoAdaptWindowsSize类中会创建一个Panel,Panel背景会自动设置,而Pannel的纯色背景会覆盖掉Form的背景。】

背景问题解决方案:给Pannel的背景色改为透明(Transparent)。如 Panel.BackColor = Color.TransParents

csharp 复制代码
    internal class AutoAdaptWindowsSize
    {
        double formOriginalWidth;//窗体高度原始宽度
        double formOriginalHeight;//窗体原始
        double scaleX;//水平缩放比例
        double scaleY;//垂直缩放比例
        Dictionary<string, string> ControlsInfo = new Dictionary<string, string>();//控件中心Left,Top,控件Width,控件Height,控件字体Size

        private Form _form;
        Panel Win_Panel1 = new Panel();
        public AutoAdaptWindowsSize(Form form)
        {
            _form = form;

            //代码生成一个容器panel1,添加至窗体
            _form.Controls.Add(Win_Panel1);
            Win_Panel1.BorderStyle = BorderStyle.None;    //容器border样式
            Win_Panel1.Dock = DockStyle.Fill;             //设置填充,下面添加控件至容器完成后,容器会填充窗口
            Win_Panel1.BackColor = Color.Transparent;    // 这里默认的背景颜色是form的背景颜色,如果form页面时图片,需要将这里的颜色设置成透明,否则会被覆盖。
            //将窗体所有控件添加至panel1
            while (_form.Controls[0].Name.Trim() != "")
            {
                foreach (Control item in _form.Controls)
                {

                    if (item.Name.Trim() != "" && item.Name.Trim() != Win_Panel1.Name.Trim())
                    {
                        Win_Panel1.Controls.Add(item);
                    }
                }
            }

            //保存窗体和控件初始大小
            InitControlsInfo(Win_Panel1);
        }

        public void InitControlsInfo(Control ctrlContainer)
        {
            if (ctrlContainer.Parent == _form)//获取窗体的高度和宽度
            {
                formOriginalWidth = Convert.ToDouble(ctrlContainer.Width);
                formOriginalHeight = Convert.ToDouble(ctrlContainer.Height);
            }
            foreach (Control item in ctrlContainer.Controls)
            {
                if (item.Name.Trim() != "")
                {
                    //添加信息:键值:控件名,内容:据左边距离,距顶部距离,控件宽度,控件高度,控件字体。
                    ControlsInfo.Add(item.Name, (item.Left + item.Width / 2) + "," + (item.Top + item.Height / 2) + "," + item.Width + "," + item.Height + "," + item.Font.Size);
                }
                if ((item as UserControl) == null && item.Controls.Count > 0)
                {
                    InitControlsInfo(item);
                }
            }

        }
        public void FormSizeChanged()
        {
            try
            {
                if (ControlsInfo.Count > 0)//如果字典中有数据,即窗体改变
                {
                    ControlsZoomScale(Win_Panel1);//表示pannel控件
                    ControlsChange(Win_Panel1);
                }
            }
            catch { }
        }
        private void ControlsZoomScale(Control ctrlContainer)
        {
            scaleX = (Convert.ToDouble(ctrlContainer.Width) / formOriginalWidth);
            scaleY = (Convert.ToDouble(ctrlContainer.Height) / formOriginalHeight);
        }

        /// <summary>
        /// 改变控件大小
        /// </summary>
        /// <param name="ctrlContainer"></param>

        private void ControlsChange(Control ctrlContainer)
        {
            double[] pos = new double[5];//pos数组保存当前控件中心Left,Top,控件Width,控件Height,控件字体Size
            foreach (Control item in ctrlContainer.Controls)//遍历控件
            {
                if (item.Name.Trim() != "")//如果控件名不是空,则执行
                {
                    if ((item as UserControl) == null && item.Controls.Count > 0)//如果不是自定义控件
                    {
                        ControlsChange(item);//循环执行
                    }
                    string[] strs = ControlsInfo[item.Name].Split(',');//从字典中查出的数据,以','分割成字符串组

                    for (int i = 0; i < 5; i++)
                    {
                        pos[i] = Convert.ToDouble(strs[i]);//添加到临时数组
                    }
                    double itemWidth = pos[2] * scaleX;     //计算控件宽度,double类型
                    double itemHeight = pos[3] * scaleY;    //计算控件高度
                    item.Left = Convert.ToInt32(pos[0] * scaleX - itemWidth / 2);//计算控件距离左边距离
                    item.Top = Convert.ToInt32(pos[1] * scaleY - itemHeight / 2);//计算控件距离顶部距离
                    item.Width = Convert.ToInt32(itemWidth);//控件宽度,int类型
                    item.Height = Convert.ToInt32(itemHeight);//控件高度
                    if (float.Parse((pos[4] * Math.Min(scaleX, scaleY)).ToString()) != 0)         //缩放字体大小不能为0
                    { item.Font = new Font(item.Font.Name, float.Parse((pos[4] * Math.Min(scaleX, scaleY)).ToString())); }  //字体
                }
            }
        }
    }

Step2. Form中引用

引用:【这个是因为我将AutoAdaptWindowsSize.cs放在Manager文件夹下了】

csharp 复制代码
using thinger.ProjectDemo.Manager;

创建全局变量

csharp 复制代码
		AutoAdaptWindowsSize AutoSize; 

在Form_Load添加如下代码,在界面初始化的过程中创建AutoSize。

csharp 复制代码
        private void FrmMain_Load(object sender, EventArgs e)
        {
            autoSize = new AutoAdaptWindowsSize(this);
        }

Step3. 创建SizeChanged事件函数

csharp 复制代码
        private void FrmMain_SizeChanged(object sender, EventArgs e)
        {
            if (autoSize != null) // 这个判断防止电脑缩放的布局不是100%时候的报错。
            {
                autoSize.FormSizeChanged();
            }
        }

Step4. 在Fram.Disiger中添加

为了解决拖动窗口时出现的严重闪屏现象。Disiger位置:

代码如下:

csharp 复制代码
using System.Windows.Forms;

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

更新时间

  • 2024.07.19
相关推荐
时光追逐者26 分钟前
分享6个.NET开源的AI和LLM相关项目框架
人工智能·microsoft·ai·c#·.net·.netcore
friklogff1 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
潮汐退涨月冷风霜1 小时前
机器学习之非监督学习(四)K-means 聚类算法
学习·算法·机器学习
GoppViper1 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
羊小猪~~1 小时前
深度学习基础案例5--VGG16人脸识别(体验学习的痛苦与乐趣)
人工智能·python·深度学习·学习·算法·机器学习·cnn
Charles Ray2 小时前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
我要吐泡泡了哦3 小时前
GAMES104:15 游戏引擎的玩法系统基础-学习笔记
笔记·学习·游戏引擎
骑鱼过海的猫1233 小时前
【tomcat】tomcat学习笔记
笔记·学习·tomcat
贾saisai5 小时前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
北岛寒沫5 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习