日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

WindowsMobile/Win Form-界面自适应

發(fā)布時(shí)間:2025/1/21 windows 67 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WindowsMobile/Win Form-界面自适应 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

起因

??? 使用SmartPhone上的WinForm做了一個(gè)WM的小程序,結(jié)果放到手機(jī)上實(shí)際一運(yùn)行。發(fā)現(xiàn)動態(tài)生成的控件在里面顯示得都非常小,難以看清。


原因

??? 我的問題是需要在InitializeComponent方法結(jié)束后,動態(tài)生成一些控件,如下:

/// <summary> /// 這個(gè)方法會根據(jù)傳入的實(shí)體模型,生成一些選擇框,設(shè)置它們的大小、位置;并會改變其它控件的大小、位置。 /// </summary> /// <param name="categories"></param> private void GenerateCheckBoxes(IList<Category> categories) { …… }

??? 原因就是因?yàn)槭謾C(jī)分辨率較大,而這些動態(tài)生成的控件并沒有進(jìn)行隨著分辨率不同而進(jìn)行自動縮放。而由界面設(shè)計(jì)器設(shè)計(jì)出來的控件,都能很好的顯示。


求索

??? 由于界面生成的控件能夠很好的自適應(yīng)分辨率的不同,所以先看一下Designer生成的代碼:

private void InitializeComponent() {this.BAdd = new System.Windows.Forms.Button();this.PCategories = new System.Windows.Forms.Panel();this.SuspendLayout(); // BAddthis.BAdd.Location = new System.Drawing.Point(165, 164);this.BAdd.Name = "BAdd";this.BAdd.Size = new System.Drawing.Size(72, 20);this.BAdd.TabIndex = 11;this.BAdd.Text = "Add";this.BAdd.Click += new System.EventHandler(this.BAdd_Click); // PCategoriesthis.PCategories.Location = new System.Drawing.Point(73, 83);this.PCategories.Name = "PCategories";this.PCategories.Size = new System.Drawing.Size(164, 75); // MainFormthis.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;this.AutoScroll = true;this.ClientSize = new System.Drawing.Size(243, 258);this.Controls.Add(this.PCategories);this.Controls.Add(this.BAdd);this.Name = "MainForm";this.Text = "MoneyManagerForm";this.ResumeLayout(false); }

??? 這里的重點(diǎn)是使用了AutoScaleDimensions和AutoScaleMode屬性來設(shè)置界面為自動縮放。(Dpi表示Dot per inch,WPF就是直接使用這種方式來控制界面的。)然后最后一步調(diào)用ResumeLayout方法,這個(gè)方法中,會調(diào)用到ContainerControl.PerformAutoScale方法進(jìn)行自動縮放。

??? 最可惡的一點(diǎn):從控件的構(gòu)造,到界面的自動縮放,全部在一個(gè)方法中實(shí)現(xiàn)!而且這個(gè)方法中,沒有什么好的辦法來調(diào)用我生成控件的方法……


解決過程

??? 在Form中,重寫ScaleControl方法如下:

protected override void ScaleControl(SizeF factor, BoundsSpecified specified) {var categories = Config.Instance.Categories;this.GenerateCheckBoxes(categories);base.ScaleControl(factor, specified); }

??? 因?yàn)檎{(diào)用過程是這樣的:

??? Control.LayoutResume() –> ContainerControl.PerformAutoScale() –> Control.Scale() –> Control.ScaleControl() & Control.ScaleChildControls()。

??? 所以,只需要重寫這個(gè)方法,就可以在真正執(zhí)行自動縮放所有控件前,先把動態(tài)控件生成。

??? 不過,這樣做同樣有局限性:因?yàn)檫@里是在InitializeComponent方法中進(jìn)行PerformAutoScale,所以這里的這些動態(tài)生成的控件,其實(shí)是在應(yīng)用程序的開始階段就已經(jīng)被明確了。相反,如果在運(yùn)行一段時(shí)間后,需要想再動態(tài)生成其它控件,就不能使用這個(gè)方法了。那時(shí),就需要直接調(diào)用剛生成的需要縮放的控件的Scale方法。而且不能直接使用PerformAutoScale方法了,因?yàn)橐WC一個(gè)控件只被調(diào)用Scale方法一次! 在這里,只需要這樣簡單實(shí)現(xiàn)就行了。:)

??? 另外,一開始以為PerformAutoScale并不會把縮放過的控件,再縮放一次,結(jié)果就寫成了這樣的錯(cuò)誤方案:

public MainForm() {InitializeComponent();//暫停布局 this.SuspendLayout(); //在InitComponents調(diào)用的PerformAutoScale方法里面,最后會把這個(gè)數(shù)給置為運(yùn)行時(shí)的數(shù)據(jù)。所以這里需要重新設(shè)置。 this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); //生成控件this.GenerateCategories();//自動縮放this.PerformAutoScale();//其實(shí)這里會把InitializeComponent中縮放的控件都再縮放一遍。//繼續(xù)布局this.ResumeLayout(false); }


結(jié)束語

??? 其實(shí),這里的自動縮放過程,在WinForm開發(fā)中,也是一樣的。

??? 而且這次實(shí)踐中,我還發(fā)現(xiàn):我在Win7的系統(tǒng)上隨手點(diǎn)了一下這個(gè)程序,居然所有功能都能夠正常的運(yùn)行……汗,當(dāng)時(shí)做的時(shí)候,可是專門為WindowsMobile開發(fā)的窗體啊。這個(gè)“跨平臺”功能,確實(shí)很強(qiáng)大,著實(shí)讓我吃驚不小。

??? 另外,由于VS2008自帶的模擬器的屏幕分辨率和設(shè)計(jì)時(shí)的分辨率是一樣大的,而我手機(jī)的分辨率比這個(gè)要大得多。所以每次調(diào)試這個(gè)縮放過程時(shí),都要生成好了,然后拷貝到手機(jī)上看效果,真是吐血……

?

?

?

引用

Windows 窗體中的自動縮放
自動縮放的執(zhí)行過程

Windows 窗體現(xiàn)在使用下面的邏輯自動對窗體及其內(nèi)容進(jìn)行縮放:

  • 設(shè)計(jì)時(shí),每一個(gè) ContainerControl 分別在 AutoScaleMode 和 AutoScaleDimensions 中記錄縮放模式和它的當(dāng)前分辨率。

  • 運(yùn)行時(shí),實(shí)際分辨率存儲在 CurrentAutoScaleDimensions 屬性中。AutoScaleFactor 屬性會動態(tài)計(jì)算運(yùn)行時(shí)分辨率與設(shè)計(jì)時(shí)分辨率的比值。

  • 當(dāng)加載窗體時(shí),如果 CurrentAutoScaleDimensions 和 AutoScaleDimensions 的值不同,則會調(diào)用 PerformAutoScale 方法對該控件及其子控件進(jìn)行縮放。此方法會掛起布局并調(diào)用 Scale 方法執(zhí)行實(shí)際縮放。然后,會更新 AutoScaleDimensions 值以避免累進(jìn)縮放。

  • 在下面的情況下還會自動調(diào)用 PerformAutoScale:

    • 在縮放模式為 Font 時(shí)響應(yīng) OnFontChanged 事件。

    • 當(dāng)繼續(xù)執(zhí)行容器控件的布局時(shí)檢測到 AutoScaleDimensions 或 AutoScaleMode 屬性發(fā)生更改。

    • 與上面的情況類似,檢測到父 ContainerControl 正在被縮放。每個(gè)容器控件只負(fù)責(zé)使用自己的比例因子縮放自己的子控件,并不負(fù)責(zé)縮放其父容器中的控件。

  • 子控件可以通過下面的若干方式修改其縮放行為:

    • 可以重寫 ScaleChildren 屬性以確定是否應(yīng)縮放其子控件。

    • 可以重寫 GetScaledBounds 方法以調(diào)整要將控件縮放至的邊界,但不調(diào)整縮放邏輯。

    • 可以重寫 ScaleControl 方法以更改當(dāng)前控件的縮放邏輯。

  • 總結(jié)

    以上是生活随笔為你收集整理的WindowsMobile/Win Form-界面自适应的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。