Windows Form 中的自動縮放比例
更新:2007 年 11 月
自動縮放比例可以讓在某台電腦上以某種顯示解析度或系統字型所設計的表單和其控制項,在另一台電腦上以不同的顯示解析度或系統字型適當地顯示。它確保表單和其控制項會智慧地調整大小,以便與使用者及其他開發人員電腦上的原生視窗和其他應用程式一致。.NET Framework 對自動縮放比例和視覺化樣式的支援,可以讓 .NET Framework 應用程式在與每個使用者電腦上的原生 Windows 應用程式相比時,都保有一致的外觀及操作。
自動縮放比例的需要
沒有自動縮放比例,專為某種顯示解析度或字型所設計的應用程式會在該解析度或字型變更時,顯示為太小或太大。例如,如果應用程式是設計為使用 Tahoma 9 點做為基礎,若沒有進行調整而在系統字型為 Tahoma 12 點的電腦上執行時,便會顯示為太小。文字項目 (例如標題、功能表、文字方塊內容等) 的顯示將會比其他應用程式還要小。此外,包含文字的使用者介面 (UI) 項目 (例如標題列、功能表和許多控制項) 的大小都取決於所使用的字型。在這個範例中,這些項目相對而言也將會顯示得較小。
當應用程式是專為某種顯示解析度而設計時,就會發生類似的情況。最通用的顯示解析度為 96 DPI (Dots Per Inch),但是支援 120、133、170 及以上較高解析度的顯示器已變得越來越普遍。如果沒有調整,專為某種解析度所設計的應用程式 (尤其是圖形架構的應用程式) 在另一種解析度上執行時,將顯示為太大或太小。
自動縮放比例會根據相對字型大小或顯示解析度,自動調整表單和其控制項的大小,以改善這些問題。Windows 作業系統支援對話方塊的自動縮放比例,此功能使用稱為對話方塊單位 (Dialog Unit,DLU) 的相對測量單位。對話方塊單位是以系統字型為基礎,而它與像素的關聯性 (Relationship) 可以透過 Win32 SDK 函式 GetDialogBaseUnits 來判斷。當使用者變更 Windows 所使用的佈景主題時,所有對話方塊都會跟著自動調整。此外,
.NET Framework 支援根據預設系統字型或顯示解析度的自動縮放比例。應用程式中的自動縮放比例可以選擇性地加以停用。
自動縮放比例的原始支援
.NET Framework 1.0 和 1.1 版以一種直接的方式支援自動縮放比例,這種方法取決於 Windows 對 UI 所使用的預設字型 (以 Win32 SDK 的 DEFAULT_GUI_FONT 值表示)。這種字型通常只有在顯示解析度變更時才會變更。下列機制在過去曾用來實作自動縮放比例:
在設計階段,AutoScaleBaseSize 屬性 (現在已被取代) 會設定為開發人員電腦上預設系統字型的高度和寬度。
在顯示表單之前,會呼叫 ApplyAutoScaling 方法來縮放表單。這個方法會從 AutoScaleBaseSize 和 Font 計算相對的縮放大小,然後呼叫 Scale 方法以實際縮放表單和其子系。
AutoScaleBaseSize 的值會更新,使後續對 ApplyAutoScaling 的呼叫不會繼續調整表單的大小。
雖然這項機制在大部分情況下已經足夠,但是仍有下列限制:
由於 AutoScaleBaseSize 屬性會將基礎字型大小顯示為整數值,因此會發生捨入錯誤,尤其當表單在多種解析度之間切換時更為明顯。
自動縮放比例只會在 Form 類別中實作,而不會在 ContainerControl 類別中。因此,只有在使用者控制項是以與表單相同的解析度所設計,並且在設計階段時置於表單中,使用者控制項才能正確縮放。
只有在多位開發人員的電腦解析度相同時,才能共同設計表單和其子控制項。同樣地,它也會根據與父表單關聯的解析度來繼承表單。
它與 .NET Framework 2.0 版所採用的較新配置管理員不相容,例如 FlowLayoutPanel 和 TableLayoutPanel。
它不支援直接以顯示解析度為基礎的縮放比例,這是與 .NET Compact Framework 相容的必要條件。
雖然 .NET Framework 2.0 版中保留了這項機制,以維持回溯相容性 (Backward Compatibility),但是這項機制已經被更穩固的縮放比例機制 (下一節所述) 所取代。因此,AutoScale、ApplyAutoScaling、AutoScaleBaseSize 和某些 Scale 多載會標記為已過時。
注意事項: |
---|
當您將舊版程式碼升級為 .NET Framework 2.0 版,便可以安全地刪除這些成員的參考。 |
自動縮放比例的目前支援
.NET Framework 2.0 版克服了上述限制,對 Windows Form 的自動縮放比例採用下列變更:
縮放比例的基礎支援已移至 ContainerControl 類別,因此表單、原生複合控制項 (Composite Control) 和使用者控制項都獲得統一的縮放比例支援。同時,也加入新成員 AutoScaleFactor、AutoScaleDimensions、AutoScaleMode 和 PerformAutoScale。
Control 類別也具有幾個新成員,使它可以參與縮放比例和支援相同表單上的混合縮放比例。Scale、ScaleChildren 和 GetScaledBounds 成員尤其支援縮放比例。
以螢幕解析度為基礎的縮放比例支援已經加入至補充的系統字型支援,如 AutoScaleMode 列舉型別 (Enumeration) 所定義。這個模式與 .NET Compact Framework 所支援的自動縮放比例相容,使得應用程式移轉更加容易。
與配置管理員 (例如 FlowLayoutPanel 和 TableLayoutPanel) 的相容性已經加入至自動縮放比例的實作。
縮放比例現在以浮點值表示 (通常使用 SizeF 結構),因此捨入錯誤已實際減少。
警告: |
---|
不支援 DPI 和字型縮放比例模式的任意混合。毫無疑問地,您可以使用一種模式 (例如 DPI) 縮放使用者控制項,並使用另一種模式 (字型) 將它放置在表單上,但是將某種模式中的基底表單與從另一種模式所衍生的表單混合,可能會造成無法預期的結果。 |
執行自動縮放比例
Windows Form 目前使用下列邏輯,自動縮放表單和其內容:
在設計階段,每個 ContainerControl 會記錄縮放比例模式,以及分別在 AutoScaleMode 和 AutoScaleDimensions 中的目前解析度。
在執行階段,實際的解析度會儲存在 CurrentAutoScaleDimensions 屬性中。AutoScaleFactor 屬性會動態計算在執行階段和設計階段的縮放比例解析度之間的比例。
當表單載入時,如果 CurrentAutoScaleDimensions 和 AutoScaleDimensions 的值不同,便會呼叫 PerformAutoScale 方法以縮放控制項和其子系。這個方法會暫止配置並呼叫 Scale 方法,以執行實際的縮放比例。然後,便會更新 AutoScaleDimensions 的值,以避免繼續縮放比例。
在下列情況下,也會自動叫用 PerformAutoScale:
當縮放比例模式為 Font 時,回應 OnFontChanged 事件。
當繼續容器控制項的配置,並在 AutoScaleDimensions 或 AutoScaleMode 屬性中偵測到變更時。
如上所指,當縮放父 ContainerControl 時。每個容器控制項都負責使用自已的縮放比例 (而非其父容器的縮放比例),來縮放其子系。
子控制項可以透過幾種方式,修改其縮放比例行為:
可以覆寫 ScaleChildren 屬性,以判斷是否應該縮放其子控制項。
可以覆寫 GetScaledBounds 方法,以調整控制項的縮放界限,而非縮放比例邏輯。
可以覆寫 ScaleControl 方法,以變更目前控制項的縮放比例邏輯。