针对 .Net Framework 4.7 的应用程序,并在 Windows 10 v1703(创作者更新版本号15063)下运行。使用Windows 10下的.Net 4.7(v1703),微软进行了很多DPI改进。
从 .NET Framework 4.7 开始,Windows Forms 包括了许多高 DPI 和动态 DPI 场景的增强,其中包括:
提高了一些 Windows Forms 控件的缩放和布局,例如 MonthCalendar 控件和 CheckedListBox 控件。
单次缩放,.NET Framework 4.6 及更早版本的缩放是通过多次传递来完成的,这导致某些控件被缩放得过多。
支持动态 DPI 场景,即用户在启动 Windows Forms 应用程序后更改 DPI 或比例因子。
为了支持它,请向您的应用程序添加一个应用程序清单(manifest),并表明您的应用程序支持 Windows 10:
<compatibility xmlns="urn:schemas-microsoft.comn:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
接下来,添加一个app.config
文件并声明应用程序为Per Monitor Aware。现在这是在app.config文件中完成的,而不是像以前一样在清单中完成!
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
这个 PerMonitorV2 是自 Windows 10 Creator 更新后的新功能:
DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
也称为 Per Monitor v2。是原始每监视器 DPI 感知模式的升级版,使应用程序能够以每个顶级窗口为基础访问新的 DPI 相关缩放行为。
子窗口 DPI 更改通知 - 在 Per Monitor v2 上下文中,整个窗口树将收到任何发生的 DPI 更改通知。
非客户区域的缩放 - 所有窗口将自动以 DPI 敏感方式绘制其非客户区域。调用 EnableNonClientDpiScaling 是不必要的。
Win32 菜单的缩放 - 在 Per Monitor v2 上下文中创建的所有 NTUSER 菜单将按照每个监视器的方式进行缩放。
对话框缩放 - 在 Per Monitor v2 上下文中创建的 Win32 对话框会自动响应 DPI 更改。
comctl32 控件的改进缩放行为 - 在 Per Monitor v2 上下文中,各种 comctl32 控件具有改进的 DPI 缩放行为。
改进的主题行为 - 在 Per Monitor v2 窗口上下文中打开的 UxTheme 句柄将以与该窗口关联的 DPI 进行操作。
现在您可以订阅 3 种新事件来获取有关 DPI 更改的通知:
Control.DpiChangedAfterParent,当控件的 DPI 设置在其父控件或表单发生 DPI 更改事件后通过编程方式更改时触发。
Control.DpiChangedBeforeParent,当控件的 DPI 设置在其父控件或表单发生 DPI 更改事件之前通过编程方式更改时触发。
Form.DpiChanged,当显示设备的 DPI 设置更改时触发。
您还有 3 个关于 DPI 处理/缩放的帮助方法:
Control.LogicalToDeviceUnits,将值从逻辑像素转换为设备像素。
Control.ScaleBitmapLogicalToDevice,将位图图像按设备的逻辑 DPI 进行缩放。
Control.DeviceDpi,返回当前设备的 DPI。
如果仍然存在问题,您可以通过应用程序配置条目退出 DPI 改进。
如果您无法访问源代码,则可以在 Windows Explorer 中的应用程序属性中选择兼容性,然后选择 System (Enhanced)
这将激活 GDI
NumericUpDown
的Margin
也不能很好地进行缩放,似乎它被缩放了两次。如果我将其缩放一次,它看起来就好了。 - ygoe