(转载)WinForm窗体控件自适应

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


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;
            }
        }
    }
 
}

在窗体Form的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);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值