时间:2016-12-7来源:本站原创作者:佚名

C#WinForm窗体及其控件自适应各种屏幕分辨率

一.说明

  我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。因为窗体上控件的位置和大小是相对于自己所在的窗体的,也就是所谓的窗口坐标。   在这里我们只考虑相对于自己窗体的窗口坐标更简单,也就是成比例变化。为了多个窗体共用,我在这里创建一个类AutoSizeFormClass ,1.使用它去记录窗体和其控件的初始位置和大小,2.根据窗体变化了的大小,成比例地实现其控件的水平和垂直方向的变化,也就是自适应。二.使用方法   使用方法很简单,   1.把自适应的类整体复制到你的工程命名空间里,   然后在需要自适应的窗体中做3步即可:   2.声明自适应类实例。   3.为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件初始位置和大小   4.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应。

三.完整代码如下:(一).自适应窗体的代码:

usingSystem;usingSystem.Windows.Forms;

namespaceWindowsFormsApplication1{publicpartialclassForm1:Form{//1.声明自适应类实例AutoSizeFormClassasc=newAutoSizeFormClass();publicForm1(){InitializeComponent();//如果加入皮肤,则不能在Form1_Load中记录控件的大小和位置,因为有些控件如dataGridView的子控件还未完成//而要在在Form1_SizeChanged中,第一次改变时,记录控件的大小和位置this.skinEngine1.SkinFile=EmeraldColor1.ssk;}//2.为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件的初始位置和大小privatevoidForm1_Load(objectsender,EventArgse){//asc.controllInitializeSize(this);}//3.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应privatevoidForm1_SizeChanged(objectsender,EventArgse){asc.controlAutoSize(this);//this.WindowState=(System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化}

}

}

(二).自适应类的代码

usingSystem.Collections.Generic;usingSystem.Windows.Forms;

namespaceWindowsFormsApplication1{classAutoSizeFormClass{//(1).声明结构,只记录窗体和其控件的初始位置和大小。publicstructcontrolRect{publicintLeft;publicintTop;publicintWidth;publicintHeight;}//(2).声明1个对象//注意这里不能使用控件列表记录ListnCtrl;,因为控件的关联性,记录的始终是当前的大小。//publicListoldCtrl=newList();//这里将西文的大于小于号都过滤掉了,只能改为中文的,使用中要改回西文publicListcontrolRectoldCtrl=newListcontrolRect();intctrlNo=0;//1;//(3).创建两个函数//(3.1)记录窗体和其控件的初始位置和大小,publicvoidcontrollInitializeSize(ControlmForm){controlRectcR;cR.Left=mForm.Left;cR.Top=mForm.Top;cR.Width=mForm.Width;cR.Height=mForm.Height;oldCtrl.Add(cR);//第一个为窗体本身,只加入一次即可

AddControl(mForm);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用

//this.WindowState=(System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化//0-Normalize,1-Minimize,2-Maximize}

privatevoidAddControl(Controlctl){foreach(Controlcinctl.Controls){//**放在这里,是先记录控件的子控件,后记录控件本身//if(c.Controls.Count0)//AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用controlRectobjCtrl;objCtrl.Left=c.Left;objCtrl.Top=c.Top;objCtrl.Width=c.Width;objCtrl.Height=c.Height;oldCtrl.Add(objCtrl);//**放在这里,是先记录控件本身,后记录控件的子控件if(c.Controls.Count0)AddControl(c);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用

}}

//(3.2)控件自适应大小,publicvoidcontrolAutoSize(ControlmForm){if(ctrlNo==0){//*如果在窗体的Form1_Load中,记录控件原始的大小和位置,正常没有问题,但要加入皮肤就会出现问题,因为有些控件如dataGridView的的子控件还没有完成,个数少//*要在窗体的Form1_SizeChanged中,第一次改变大小时,记录控件原始的大小和位置,这里所有控件的子控件都已经形成controlRectcR;//cR.Left=mForm.Left;cR.Top=mForm.Top;cR.Width=mForm.Width;cR.Height=mForm.Height;cR.Left=0;cR.Top=0;cR.Width=mForm.PreferredSize.Width;cR.Height=mForm.PreferredSize.Height;oldCtrl.Add(cR);//第一个为窗体本身,只加入一次即可

AddControl(mForm);//窗体内其余控件可能嵌套其它控件(比如panel),故单独抽出以便递归调用}floatwScale=(float)mForm.Width/(float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体floathScale=(float)mForm.Height/(float)oldCtrl[0].Height;//.Height;ctrlNo=1;//进入=1,第0个为窗体本身,窗体内的控件,从序号1开始

AutoScaleControl(mForm,wScale,hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用}

privatevoidAutoScaleControl(Controlctl,floatwScale,floathScale){intctrLeft0,ctrTop0,ctrWidth0,ctrHeight0;//intctrlNo=1;//第1个是窗体自身的Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始foreach(Controlcinctl.Controls){//**放在这里,是先缩放控件的子控件,后缩放控件本身//if(c.Controls.Count0)//AutoScaleControl(c,wScale,hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用ctrLeft0=oldCtrl[ctrlNo].Left;ctrTop0=oldCtrl[ctrlNo].Top;ctrWidth0=oldCtrl[ctrlNo].Width;ctrHeight0=oldCtrl[ctrlNo].Height;//c.Left=(int)((ctrLeft0-wLeft0)*wScale)+wLeft1;//新旧控件之间的线性比例//c.Top=(int)((ctrTop0-wTop0)*h)+wTop1;c.Left=(int)((ctrLeft0)*wScale);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加+wLeft1c.Top=(int)((ctrTop0)*hScale);//c.Width=(int)(ctrWidth0*wScale);//只与最初的大小相关,所以不能与现在的宽度相乘(int)(c.Width*w);c.Height=(int)(ctrHeight0*hScale);//ctrlNo++;//累加序号//**放在这里,是先缩放控件本身,后缩放控件的子控件if(c.Controls.Count0)AutoScaleControl(c,wScale,hScale);//窗体内其余控件还可能嵌套控件(比如panel),要单独抽出,因为要递归调用

}}

}}









































哈市白癜风医院
白癜风传染么

转载请注明原文网址:http://www.gzdatangtv.com/bcyykf/3846.html
------分隔线----------------------------