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

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

一。说明

  我们自己编写程序的界面,会遇到各种屏幕分辨率,只有自适应才能显的美观。实际上,做到这点也很简单,就是首先记录窗体和它上面控件的初始位置和大小,当窗体改变比例时,其控件的位置和大小也按此比例变化即可。因为窗体上控件的位置和大小是相对于自己所在的窗体的,也就是所谓的窗口坐标。
  在这里我们只考虑相对于自己窗体的窗口坐标更简单,也就是成比例变化。为了多个窗体共用,我在这里创建一个类AutoSizeFormClass ,1.使用它去记录窗体和其控件的初始位置和大小,2.根据窗体变化了的大小,成比例地实现其控件的水平和垂直方向的变化,也就是自适应。

二。使用方法
  使用方法很简单,
  1.把自适应的类整体复制到你的工程命名空间里,
   然后在需要自适应的窗体中做3步即可:
  2.声明自适应类实例。
  3.为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件初始位置和大小
  4.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应

三。完整代码如下:

(一)。自适应窗体的代码:

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.ComponentModel; 
  4. using System.Data; 
  5. using System.Drawing; 
  6. using System.Text; 
  7. using System.Windows.Forms; 
  8. namespace WindowsApplication1 
  9.     public partial class Form1 : Form 
  10.     { 
  11.         //1.声明自适应类实例 
  12.         AutoSizeFormClass asc = new AutoSizeFormClass(); 
  13.         public Form1() 
  14.         { 
  15.             InitializeComponent(); 
  16.         } 
  17.         //2. 为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件的初始位置和大小 
  18.         private void Form1_Load(object sender, EventArgs e) 
  19.         { 
  20.             asc.controllInitializeSize(this); 
  21.         } 
  22.         //3.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应 
  23.         private void Form1_SizeChanged(object sender, EventArgs e) 
  24.         { 
  25.             asc.controlAutoSize(this); 
  26.         } 
  27.     } 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        //1.声明自适应类实例
        AutoSizeFormClass asc = new AutoSizeFormClass();
        public Form1()
        {
            InitializeComponent();
        }
        //2. 为窗体添加Load事件,并在其方法Form1_Load中,调用类的初始化方法,记录窗体和其控件的初始位置和大小
        private void Form1_Load(object sender, EventArgs e)
        {
            asc.controllInitializeSize(this);
        }
        //3.为窗体添加SizeChanged事件,并在其方法Form1_SizeChanged中,调用类的自适应方法,完成自适应
        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            asc.controlAutoSize(this);
        }
    }
}



(二)。自适应类的代码

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Text; 
  4. using System.Windows.Forms; 
  5. namespace WindowsApplication1 
  6.     class AutoSizeFormClass 
  7.     { 
  8.         //(1).声明结构,只记录窗体和其控件的初始位置和大小。 
  9.         public struct controlRect 
  10.         { 
  11.             public int Left; 
  12.             public int Top; 
  13.             public int Width; 
  14.             public int Height; 
  15.         } 
  16.         //(2).声明 1个对象 
  17.         //注意这里不能使用控件列表记录 List<Control> nCtrl;,因为控件的关联性,记录的始终是当前的大小。 
  18.          public List<controlRect> oldCtrl; 
  19.         //int ctrl_first = 0; 
  20.         //(3). 创建两个函数 
  21.         //(3.1)记录窗体和其控件的初始位置和大小, 
  22.         public void controllInitializeSize(Form mForm) 
  23.         { 
  24.             // if (ctrl_first == 0) 
  25.             { 
  26.                 //  ctrl_first = 1; 
  27.                 oldCtrl = new List<controlRect>(); 
  28.                 controlRect cR; 
  29.                 cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height; 
  30.                 oldCtrl.Add(cR); 
  31.                 foreach (Control c in mForm.Controls) 
  32.                 { 
  33.                     controlRect objCtrl; 
  34.                     objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height; 
  35.                     oldCtrl.Add(objCtrl); 
  36.                 } 
  37.             } 
  38.             // this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化 
  39.             //0 - Normalize , 1 - Minimize,2- Maximize 
  40.         } 
  41.         //(3.2)控件自适应大小, 
  42.         public void controlAutoSize(Form mForm) 
  43.         { 
  44.             //int wLeft0 = oldCtrl[0].Left; ;//窗体最初的位置 
  45.             //int wTop0 = oldCtrl[0].Top; 
  46.             int wLeft1 = this.Left;//窗体当前的位置 
  47.             //int wTop1 = this.Top; 
  48.             float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体 
  49.             float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height; 
  50.             int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0; 
  51.             int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始 
  52.             foreach (Control c in mForm.Controls) 
  53.             { 
  54.                 ctrLeft0 = oldCtrl[ctrlNo].Left; 
  55.                 ctrTop0 = oldCtrl[ctrlNo].Top; 
  56.                 ctrWidth0 = oldCtrl[ctrlNo].Width; 
  57.                 ctrHeight0 = oldCtrl[ctrlNo].Height; 
  58.                 //c.Left = (int)((ctrLeft0 - wLeft0) * wScale) + wLeft1;//新旧控件之间的线性比例 
  59.                 //c.Top = (int)((ctrTop0 - wTop0) * h) + wTop1; 
  60.                 c.Left = (int)((ctrLeft0) * wScale);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加 + wLeft1 
  61.                 c.Top = (int)((ctrTop0) * hScale);// 
  62.                 c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 (int)(c.Width * w); 
  63.                 c.Height = (int)(ctrHeight0 * hScale);// 
  64.                 ctrlNo += 1; 
  65.             } 
  66.         } 
  67.        
  68.     } 
  69.   
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
    class AutoSizeFormClass
    {
        //(1).声明结构,只记录窗体和其控件的初始位置和大小。
        public struct controlRect
        {
            public int Left;
            public int Top;
            public int Width;
            public int Height;
        }
        //(2).声明 1个对象
        //注意这里不能使用控件列表记录 List<Control> nCtrl;,因为控件的关联性,记录的始终是当前的大小。
         public List<controlRect> oldCtrl;
        //int ctrl_first = 0;
        //(3). 创建两个函数
        //(3.1)记录窗体和其控件的初始位置和大小,
        public void controllInitializeSize(Form mForm)
        {
            // if (ctrl_first == 0)
            {
                //  ctrl_first = 1;
                oldCtrl = new List<controlRect>();
                controlRect cR;
                cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
                oldCtrl.Add(cR);
                foreach (Control c in mForm.Controls)
                {
                    controlRect objCtrl;
                    objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;
                    oldCtrl.Add(objCtrl);
                }
            }
            // this.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后,再最大化
            //0 - Normalize , 1 - Minimize,2- Maximize
        }
        //(3.2)控件自适应大小,
        public void controlAutoSize(Form mForm)
        {
            //int wLeft0 = oldCtrl[0].Left; ;//窗体最初的位置
            //int wTop0 = oldCtrl[0].Top;
            int wLeft1 = this.Left;//窗体当前的位置
            //int wTop1 = this.Top;
            float wScale = (float)mForm.Width / (float)oldCtrl[0].Width;//新旧窗体之间的比例,与最早的旧窗体
            float hScale = (float)mForm.Height / (float)oldCtrl[0].Height;//.Height;
            int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;
            int ctrlNo = 1;//第1个是窗体自身的 Left,Top,Width,Height,所以窗体控件从ctrlNo=1开始
            foreach (Control c in mForm.Controls)
            {
                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);//新旧控件之间的线性比例。控件位置只相对于窗体,所以不能加 + wLeft1
                c.Top = (int)((ctrTop0) * hScale);//
                c.Width = (int)(ctrWidth0 * wScale);//只与最初的大小相关,所以不能与现在的宽度相乘 (int)(c.Width * w);
                c.Height = (int)(ctrHeight0 * hScale);//
                ctrlNo += 1;
            }
        }
      
    }
}
 







  当然,窗口坐标和屏幕坐标也是可以相互转换的,  

  1. private void Form1_MouseDown(object sender, MouseEventArgs e) 
  2.    int x = e.X; //相对form窗口的坐标,客户区坐标 
  3.    int y = e.Y; 
  4.    int x1 = Control.MousePosition.X;//相对显示器,屏幕的坐标 
  5.    int y1 = Control.MousePosition.Y;   
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
   int x = e.X; //相对form窗口的坐标,客户区坐标
   int y = e.Y;
   int x1 = Control.MousePosition.X;//相对显示器,屏幕的坐标
   int y1 = Control.MousePosition.Y;  
}


它们之间转换如下:
this.Location; // 窗体所在坐标
this.PointToScreen(new Point(0, 0)); // 客户区坐标转换为屏幕坐标
this.PointToClient(new Point(0, 0)); // 屏幕坐标转换为客户区坐标

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值