1、問題分析web
winform程序在不一樣分辨率下產生界面混亂的主要緣由是,默認狀況下winform程序的座標是基於Point(點)的,Point與DPI(分辨率,每英寸所打印點數)相關。當DPI發生變化時,顯示在界面上的尺寸根據DPI自動變化,致使界面與設計之初產生錯亂。c#
2、解決方案函數
方案1 利用AutoScaleMode 屬性,將窗體的AutoScaleMode 屬性設置爲Dpi。佈局
Dpi:根據顯示分辨率控制縮放。經常使用分辨率爲 96 和 120 DPI。 字體
Font:根據類使用的字體(一般爲系統字體)的維度控制縮放。 this
Inherit:根據類的父類的縮放模式控制縮放。若是不存在父類,則禁用自動縮放。 spa
None:禁用自動縮放。設計
方案2 借鑑web程序中以pixel(像素)爲經常使用單位,在winform程序中使用像素來定位,在Form的構造函數中將窗體的AutoScaleMode 屬性設置爲Font。code
private void InitializeComponent() { //設定按字體來縮放控件 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; //設定字體大小爲12px this.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134))); }
方案3 記錄下1920*1080分辨率下工做區域的Width和Height,記做DefaultWidth和DefaultHeight,用改變分辨率以後的工做區域的Width和Height去分別除DefaultWidth和DefaultHeight,獲得縮放比例,再調整主界面和各控件的縮放。orm
public class AutoReSizeForm { static float SH { get { return (float)Screen.PrimaryScreen.Bounds.Height / DefaultHeight; } } static float SW { get { return (float)Screen.PrimaryScreen.Bounds.Width / DefaultWidth; } } public static void SetFormSize(Control fm) { fm.Location = new Point((int)(fm.Location.X * SW), (int)(fm.Location.Y * SH)); fm.Size = new Size((int)(fm.Size.Width * SW), (int)(fm.Size.Height * SH)); fm.Font = new Font(fm.Font.Name, fm.Font.Size * SH,fm.Font.Style,fm.Font.Unit,fm.Font.GdiCharSet,fm.Font.GdiVerticalFont); if (fm.Controls.Count!=0) { SetControlSize(fm); } } private static void SetControlSize(Control InitC) { foreach (Control c in InitC.Controls) { c.Location = new Point((int)(c.Location.X * SW), (int)(c.Location.Y * SH)); c.Size = new Size((int)(c.Size.Width * SW), (int)(c.Size.Height * SH)); c.Font = new Font(c.Font.Name, c.Font.Size * SH, c.Font.Style, c.Font.Unit, c.Font.GdiCharSet, c.Font.GdiVerticalFont); if (c.Controls.Count != 0) { SetControlSize(c); } } } }
3、方案分析
方案1和方案2存在必定問題,一方面,在MSDN裏有一條警告是不支持在同一窗口裏將DPI模式和Font模式混合使用;另外一方面,根據網上的實際經驗,自動放縮和窗口布局的Dock、Anchor有時也會有衝突,也就是說目前採用方案1和方案2的自動放縮功能仍不夠理想。
方案3的效果有待進一步探究。