自动缩放功能可以让窗体及其控件在一种显示分辨率或字体下设计,并在另一种不同显示分辨率或字体的计算机上正确显示。 它确保窗体及其控件可智能调整大小,使其与用户和其他开发人员计算机上的本机窗口和其他应用程序保持一致。 自动缩放和视觉样式使 Windows 窗体应用程序能够在每个用户计算机上与本机 Windows 应用程序相比,保持一致的外观和用户体验。
在大多数情况下,Windows 窗体中的自动缩放能够按预期运行。 但是,字体方案更改可能会有问题。 有关如何解决此问题的示例,请参阅如何:在 Windows 窗体应用程序中响应字体方案更改。
自动缩放的必要性
如果没有自动缩放,设计用于一个显示分辨率或字体的应用程序会在更改分辨率或字体时显示过小或太大。 例如,如果应用程序使用 Tahoma 9 点作为基线进行设计,且未做调整,那么在系统字体为 Tahoma 12 点的计算机上运行时,它会显得太小。 文本元素(如标题、菜单、文本框内容等)将显示得比其他应用程序更小。 此外,包含文本的用户界面(UI)元素的大小,如标题栏、菜单和许多控件都依赖于使用的字体。 在此示例中,这些元素也会显得相对较小。
当应用程序设计为特定显示分辨率时,会出现类似的情况。 最常见的显示分辨率是每英寸96个点(DPI),相当于100%的缩放比例,但支持125%、150%、200%(分别对应120、144和192 DPI)及更高分辨率的显示器变得越来越常见。 如果不进行调整,应用程序(尤其是基于图形的应用程序)在以另一分辨率运行时,针对一个分辨率设计的分辨率将显得太大或太小。
自动缩放通过根据相对字号或显示分辨率自动调整窗体及其子控件的大小来解决这些问题。 Windows 操作系统支持使用称为对话框单位的相对度量单位自动缩放对话框。 对话单元基于系统字体,其与像素的关系可以通过 Win32 SDK 函数 GetDialogBaseUnits
确定。 当用户更改 Windows 使用的主题时,将自动相应地调整所有对话框。 此外,Windows 窗体支持根据默认系统字体或显示分辨率自动缩放。 (可选)可以在应用程序中禁用自动缩放。
谨慎
不支持 DPI 和字体缩放模式的任意混合。 尽管您可以使用一种模式(例如 DPI)缩放用户控件,并使用另一种模式(字体)在窗体上放置该控件,通常不会出现问题,但如果以一种模式为基准形式,并在另一种模式下使用派生形式,可能会产生意外的结果。
操作中的自动缩放
Windows 窗体使用以下逻辑自动缩放窗体及其内容:
在设计时,每个 ContainerControl 分别在 AutoScaleMode 和 AutoScaleDimensions 中记录缩放模式及其当前的分辨率。
在运行时,实际分辨率存储在 CurrentAutoScaleDimensions 属性中。 AutoScaleFactor 属性动态计算运行时和设计时缩放分辨率之间的比率。
当窗体加载时,如果 CurrentAutoScaleDimensions 和 AutoScaleDimensions 的值不同,则调用 PerformAutoScale 方法以缩放控件及其子元素。 此方法暂停布局并调用 Scale 方法进行缩放。 随后将更新 AutoScaleDimensions 的值以避免渐进式缩放。
在以下情况下,也会自动调用 PerformAutoScale:
如果缩放模式为 OnFontChanged,则响应 Font 事件。
当容器控件的布局继续执行并在 AutoScaleDimensions 或 AutoScaleMode 属性中检测到更改时。
如上所述,当父 ContainerControl 正在缩放时。 每个容器控件负责使用自己的比例因子(而不是其父容器的比例因子)缩放其子控件。
子控件可通过多种方式修改其缩放行为:
可重写 ScaleChildren 属性以确定是否应缩放其子控件。
可重写 GetScaledBounds 方法以调整控件缩放到的边界,但不是调整缩放逻辑。
可重写 ScaleControl 方法以更改当前控件的缩放逻辑。