WinForm控件自适应(实现不同像素自适应,字体自适应,改变窗体大小自适应)

2023-05-16

今天给大家上一道硬菜。本来不爱鸡汤,今天说两句:winform开发有一个缺陷就是不能实现界面的自适应,切换不同的分辨率,或者窗体大小改变就会出现窗体显示不全的问题。这就需要自己写一个方法来实现不同情况下的自适应,WPF比Winform的一个显著优势就是可以实现自适应。今天给大家一个可以实现自适应的方案。(本篇博客代码,为本人,在本地调试通过后,手敲到博客中,难免出现敲错的状况,勿喷。代码里面的注释是比较清楚的)

效果图:

 

调整大小后

新建一个AutoSizeFormClass.cs文件

class AutoSizeFormClass
{
    //1.声明一个结构体,记录窗体和控件的基本属性
    public struct controlRect
    {
        public string Name;
        public int Left;
        public int Top;
        public int Width;
        public int Height;
        public float FontSize;
        public FontFamily FontFamily;
    }
    //2.声明一个集合记录所有控件的属性
    //使用控件的Name作为key
    Dictionary<string,controlRect> dic=new Dictionary<string,controlRect>();
    int ctrNo=0;
    //这里是你开发环境下的分辨率
    private int ScW=1920;
    private int ScH=1080;
    //记录窗体是不是第一次加载的标记 0:第一次加载  1:重复加载
    private int IsFirstLoad=0;
    //窗体的名称
    private string FrmName=string.Empty;
    //3.创建两个函数
    //采用递归的方法将控件包含的所有控件属性记录下来(结构体的每一个属性都需要赋值)
    private void AddControl(Control ctl)
    {
        foreach(Control c in ctl.Controls)
        {
            GetCtrParameter(c);
            //使用递归函数先记录控件本身,后记录控件包含的子控件
            if(c.Controls.Count>0)
            {
                AddControl(c);
            }
        }
    }
    //获取控件的所有属性
    private void GetCtrParameter(Control mForm)
    {
        controlRect cr;
        cr.Name=mForm.Name;
        cr.Left=mForm.Left;
        cr.Top=mForm.Top;
        cr.Width=mForm.Width;
        cr.Height=mForm.Height;
        cr.FontSize=mForm.Font.Size;
        cr.FontFamily=mForm.Font.FontFamily;
        dic.Add(cr.Name,cr);
    }

    //4.控件自适应大小
    public void controlAutoSize(Control mForm)
    {
        FrmName=mForm.Name;
        float wScale=0;
        float hScale=0;
        //因为有些控件和DataGridView的子空间加载时间较长,所以在Form1_SizeChanged中,
        //记录控件的原始大小和位置,第一次加载的时候先根据和开发环境的像素比例绘制窗体                
        if(IsFirstLoad==0&&ctrNo==0)
        {
            //获取当前的像素
            int SH=Screen.PrimaryScreen.Bounds.Height;
            int SW=Screen.PrimaryScreen.Bounds.Width;
            //和开发环境的像素相比获取对应的比值
            wScale=(float)SH/(float)ScH;
            hScale=(float)SW/(float)ScW;
            controlRect cR;
            cR.Name=mForm.Name;
            cR.Left=mForm.Left;
            cR.Top=mForm.Top;
            cR.Width=mForm.Width;
            cR.Height=mForm.Height;
            cR.FontSize=mForm.Font.Size;
            cR.FontFamily=mForm.Font.FontFamily;
            dic.Add(cR.Name,cR);//第一个为窗体本身
            AddControl(mForm);//递归获取所有窗体基础信息
            AutoScaleControl(mForm,wScale,hScale);//这里其实是第一次构造窗体
            IsFirstLoad=1;            
        }
        //这里是改变窗体大小时重新设置窗体的属性
        else
        {
            //新旧窗体之间的高和长的比例,与第一次加载的信息比较
            wScale=(float)mForm.Width/dic[FrmName].Width;
            hScale=(float)mForm.Height/dic[FrmName].Height;
            //将ctrNo设为1,代表为控件而非窗体
            ctrNo=1;
            //设置控件以及其嵌套的控件的比例大小,使用递归调用
            AutoScaleControl(mForm,wScale,hScale);
        }
    }
    //递归进行自适应调整
    private void AutoScaleControl(Control ctl,float wScale,float hScale)
    {
        int ctrLeft0,ctrTop0,ctrWidth0,ctrHeight0;
        float fontSize;
        FontFamily fontFamily;
        foreach(Control c in ctl.Controls)
        {
            string ctrName=c.Name;
            ctrLeft0=dic[ctrName].Left;
            ctrTop0=dic[ctrName].Top;
            ctrWidth0=dic[ctrName].Width;
            ctrHeight0=dic[ctrName].Height;
            fontSize=dic[ctrName].FontSize;
            fontFamily=dic[ctrName].FontFamily;
            //新旧控件之间的线性比例,字体大小依据高度转换
            c.Left=(int)(ctrLeft0*wScale);
            c.Top=(int)(ctrTop0*hScale);
            c.Width=(int)(ctrWidth0*wScale);
            c.Height=(int)(ctrHeight0*hScale);
            c.Font=new Font(fontFamily,fontSize*hScale);
            ctrNo++;
            //先缩放控件本身,后缩放控件的子控件
            if(c.Controls.Count>0)
            {
                AutoScaleControl(c,wScale,hScale);
            }
            //dataGridview特殊处理
            if(c is DataGridView)
            {
                DataGridView dgv=c as DataGridView;
                Cursor.Current=Cursors.WaitCursor;
                int widths=0;
                for(int i=0;i<dgv.Columns.Count-1;i++)
                {
                    //自动调整列宽
                    dgv.AutoResizeColumn(i,DataGridViewAutoSizeColumnMode.AllCells);
                    widths+=dgv.Columns[i].Width;
                }
                //如果调整列的宽度大于设定宽度
                if(widths>ctl.Size.Width)
                {
                                dgv.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.DisplayedCells;//调整列的模式

                }
                else
                {
                    dgv.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.Fill;//如果小于则填充
                   
                }
                 Cursor.Current=Cursors.Default;
            }
        }
    }

}

添加一个Form1,在SizeChanged方法添加,不要在load中添加

public partial class Form1:Form
{
    private AutoSizeFormClass asc=new AutoSizeFormClass();
    public Form1()
    {
        InitializeComponent();
    } 
    private void Form1_SizeChanged(object sender,EventArgs e)
    {
        asc.controlAutoSize(this);
    }
}

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WinForm控件自适应(实现不同像素自适应,字体自适应,改变窗体大小自适应) 的相关文章

随机推荐

  • Oracle数据库常见对象-索引、视图、存储过程、函数和触发器

    转发来源 xff1a https blog csdn net someonemh article details 80773582 以下总结常见的数据库对象 xff0c 供自己复习 如有错误希望指出 xff0c 共同学习 xff01 一 索
  • 数据治理

    全球数据战略公司董事总经理Donna Burbank说 xff1a 人工智能只有建立在优质的数据基础上才能成功 xff0c 从而推动了数据治理的发展 Thomas C Redman博士说 xff1a 估计80 的人工智能 xff08 AI
  • B端产品的输入与选择组件

    二者的定义 xff1b 作用是什么 xff1f 二者的定义 输入组件是让用户自行输入 xff0c 范围不确定 xff0c 想输什么就可以进行填写在输入的过程中通常使用到键盘 也就意味着输入的难度较大 一般会用于名称 手机号 地址 邮箱等 x
  • HDFS上传文件的命令使用

    打开Hadoop xff0c sbin start all sh 上传文件 xff1a bin hadoop fs put home xleer 1 txt user hadoop input1 查看HDFS中的文件 xff1a bin h
  • java list倒序输出及复制list集合

    有时我们需要把java list集合倒序输入 xff0c java list倒序输出其实很简单 xff0c 就一行代码就可以把原有的list倒序过来了 如原来有一个集合list xff0c list里面是有数据的 xff0c 现在如果把li
  • hbase命令集(shell 命令,如建表,清空表,增删改查)

    两篇可以参考的文章 xff0c 讲的不错 http www cnblogs com nexiyi p hbase shell html http blog iyunv com wulantian article details 410112
  • 关于纯净的win7旗舰版安装后无无线网驱动问题

    由于经济问题 xff0c 笔者的本本从11年一直用到现在 xff0c 之前也因为月咏越卡 xff0c 重装过很多次的系统 xff0c 这次听说安装纯净版的系统汇比较快 xff0c 于是乎上网搜了一下 xff0c 下载了微软的win7旗舰版的
  • 可用性和可靠性的区别

    可用性和可靠性区别简介 可用性 xff08 Availability xff09 是关于系统可供使用时间的描述 xff0c 以丢失的时间为驱动 xff08 Be Driven By Lost Time xff09 可靠性 xff08 Rel
  • linux平台上的TCP并发服务

    实验一 xff1a linux平台上的TCP并发服务 xff08 4学时 xff09 题目 掌握基本套接字函数使用方法 TCP协议工作原理 并发服务原理和编程方法 实验内容 xff1a 在linux平台上实现1个TCP并发服务器 xff0c
  • Oracle通过Navicat建表查询时表不存在的问题解决

  • 检验数据集是否服从正态分布

    1 图示法 1 p p图 以样本的累积频率作为横坐标 xff0c 以正太分布计算的响应累积概率作为纵坐标 xff0c 把样本值表现为执教坐标系中的散点 若数据集服从正太分布 xff0c 则样本点应围绕第一象限的对角线分布 1 2 QQ图 以
  • Linux下实现C语言的http请求实现

    1 前言 Linux下的http请求有许多种方式 xff0c 其中curl库是C语言封装的一个强大的库 xff0c 使用curl比封装socket更加方便 cJSON是一个小型的json封装库 xff0c 可以把数据封装成json格式 本文
  • http请求详解

    1 简介 HTTP HyperText Transfer Protocol xff0c 超文本传输协议 是一套计算机通过网络进行通信的规则 计算机专家设计出HTTP xff0c 使HTTP客户 xff08 如Web浏览器 xff09 能够从
  • Python使用subprocess执行shell命令

    import subprocess import time cmd 61 34 XX 34 svnlog1 61 subprocess Popen cmd shell 61 True stdin 61 subprocess PIPE std
  • CMake undefined reference to 问题

    Simples app src main cpp ffmpeg 3 3 3 build android arm64 v8a lib libavcodec a utils o In function 96 avcodec string 39
  • C/C++:struct 和 class 的区别

    汇总 struct 是值类型 xff0c class 是对象类型struct 默认的访问权限是 public xff0c 而class 默认的访问权限是 private struct 总是有默认的构造函数 xff0c 即使是重载默认构造函数
  • RT-DETR的学习笔记

    1 RT DETR GitHub PaddleDetection tree develop configs rtdetr 2 复现训练流程 2 1 原文使用设备 2 2 环境要求 4 v100 cuda gt 61 11 7 1 nccl
  • 【Zotero】《纯操作讲解,GPT配置,Zotero标注可视化》- 知识点目录

    纯操作讲解 xff0c GPT配置 xff0c Zotero标注可视化 1 快捷键 github 2 API设置 github Temperature分布在 0 1 0 1
  • 【OpenAI】《Zotero GPT | 如何调教你的GPT》- 知识点目录

    Zotero GPT 如何调教你的GPT 此教程讲述了tag的代码构成 xff0c ZoteroGPT中tag的效果就有点像浏览器中的插件 xff1b TimeContent0 51一个tag的基本组成5 32tag的工作原理6 33删除和
  • WinForm控件自适应(实现不同像素自适应,字体自适应,改变窗体大小自适应)

    今天给大家上一道硬菜 本来不爱鸡汤 xff0c 今天说两句 xff1a winform开发有一个缺陷就是不能实现界面的自适应 xff0c 切换不同的分辨率 xff0c 或者窗体大小改变就会出现窗体显示不全的问题 这就需要自己写一个方法来实现