1. 程式人生 > >C# WinForm窗體及其控件自適應各種屏幕分辨率

C# WinForm窗體及其控件自適應各種屏幕分辨率

mes down 初始 ear ews 復制 .text 命名空間 markdown

C# WinForm窗體及其控件自適應各種屏幕分辨率

一。說明
  我們自己編寫程序的界面,會遇到各種屏幕分辨率,只有自適應才能顯的美觀。實際上,做到這點也很簡單,就是首先記錄窗體和它上面控件的初始位置和大小,當窗體改變比例時,其控件的位置和大小也按此比例變化即可。因為窗體上控件的位置和大小是相對於自己所在的窗體的,也就是所謂的窗口坐標。
  在這裏我們只考慮相對於自己窗體的窗口坐標更簡單,也就是成比例變化。為了多個窗體共用,我在這裏創建一個類AutoSizeFormClass ,1.使用它去記錄窗體和其控件的初始位置和大小,2.根據窗體變化了的大小,成比例地實現其控件的水平和垂直方向的變化,也就是自適應。

二。使用方法
  使用方法很簡單,
  1.把自適應的類整體復制到你的工程命名空間裏,
   然後在需要自適應的窗體中做3步即可:
  2.聲明自適應類實例。
  3.為窗體添加Load事件,並在其方法Form1_Load中,調用類的初始化方法,記錄窗體和其控件初始位置和大小
  4.為窗體添加SizeChanged事件,並在其方法Form1_SizeChanged中,調用類的自適應方法,完成自適應

三。完整代碼如下:

(一)。自適應窗體的代碼:

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

(二)自適應類的代碼

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

    }  
}  

當然,窗口坐標和屏幕坐標也是可以相互轉換的,  

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)); // 屏幕坐標轉換為客戶區坐標

C# WinForm窗體及其控件自適應各種屏幕分辨率