Windows 窗体中的高 DPI 支持
从 .NET Framework 4.7 开始,Windows 窗体引入了针对高 DPI 和动态 DPI 场景的增强功能。 其中包括:
改进了一些 Windows 窗体控件的缩放和布局,例如 MonthCalendar 控件和 CheckedListBox 控件。
单通道缩放。 在 .NET Framework 4.6 及更早版本中,通过多个通道执行缩放,这导致某些控件缩放超过必要。
支持动态 DPI 方案,在此方案中,用户在启动 Windows 窗体应用程序后更改了 DPI 或缩放系数。
从 .NET Framework 4.7 开始的 .NET Framework 版本中,增强的高 DPI 支持是一项选择加入功能。 必须配置应用程序才能利用该功能。
配置 Windows 窗体应用以获得高 DPI 支持
仅在以 .NET Framework 4.7 为目标并在从 Windows 10 创意者更新开始的 Windows 操作系统上运行的应用程序中提供支持高 DPI 感知的新 Windows 窗体功能。
此外,若要在 Windows 窗体应用程序中配置高 DPI 支持,必须执行以下操作:
声明与 Windows 10 的兼容性。
为此,请将以下内容添加到清单文件:
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- Windows 10 compatibility --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> </application> </compatibility>
在 app.config 文件中启用每监视器 DPI 感知。
Windows 窗体引入了一个新的
<System.Windows.Forms.ApplicationConfigurationSection>
元素,用于支持从 .NET Framework 4.7 开始添加的新增功能和自定义项。 若要利用支持高 DPI 的新功能,请将以下内容添加到应用程序配置文件。<configuration> <!-- ... other xml settings ... --> <System.Windows.Forms.ApplicationConfigurationSection> <add key="DpiAwareness" value="PerMonitorV2" /> </System.Windows.Forms.ApplicationConfigurationSection> </configuration>
重要
在 .NET Framework 的早期版本中,你使用了清单来添加高 DPI 支持。 不再建议使用此方法,因为它会替代在 app.config 文件上定义的设置。
调用静态 EnableVisualStyles 方法。
这应该是应用程序入口点中的第一个方法调用。 例如:
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form2()); }
选择退出单个高 DPI 功能
将 DpiAwareness
值设置为 PerMonitorV2
可启用所有从 .NET Framework 4.7 版本开始支持的高 DPI 感知功能。 通常,这足以满足大多数 Windows 窗体应用程序的需求。 但是,你可能想要选择退出一个或多个单个功能。 执行此操作的最重要原因是,现有应用程序代码已处理该功能。 例如,如果应用程序处理自动缩放,建议禁用自动调整大小功能,如下所示:
<configuration>
<!-- ... other xml settings ... -->
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
<add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
</System.Windows.Forms.ApplicationConfigurationSection>
</configuration>
有关各个键及其值的列表,请参阅 Windows Forms 添加配置元素。
新的 DPI 更改事件
从 .NET Framework 4.7 开始,可通过三个新事件以编程方式处理动态 DPI 更改:
- DpiChangedAfterParent:父控件或窗体的 DPI 更改事件发生后,以编程方式更改时控件的 DPI 设置时触发。
- DpiChangedBeforeParent:父控件或窗体的 DPI 更改事件发生前,以编程方式更改时控件的 DPI 设置时触发。
- DpiChanged:当前显示窗体的显示设备上的 DPI 设置更改时触发。
新的帮助程序方法和属性
.NET Framework 4.7 还添加了许多新的帮助程序方法和属性,这些方法和属性提供有关 DPI 缩放的信息,并允许你执行 DPI 缩放。 其中包括:
LogicalToDeviceUnits:用于将值从逻辑转换为设备像素。
ScaleBitmapLogicalToDevice:用于将位图图像缩放到设备的逻辑 DPI。
DeviceDpi,返回当前设备的 DPI。
版本控制注意事项
除了在 .NET Framework 4.7 和 Windows 10 创意者更新上运行之外,应用程序还可以在与高 DPI 改进不兼容的环境中运行。 你需要在这种情况下为你的应用程序开发一个回退方案。 可以通过执行自定义绘图来处理缩放。
为此,还需要确定运行应用的操作系统。 可以使用如下所示的代码执行此操作:
// Create a reference to the OS version of Windows 10 Creators Update.
Version OsMinVersion = new Version(10, 0, 15063, 0);
// Access the platform/version of the current OS.
Console.WriteLine(Environment.OSVersion.Platform.ToString());
Console.WriteLine(Environment.OSVersion.VersionString);
// Compare the current version to the minimum required version.
Console.WriteLine(Environment.OSVersion.Version.CompareTo(OsMinVersion));
请注意,如果应用程序未在应用程序清单中列为受支持的操作系统,应用程序将无法成功检测 Windows 10。
还可以检查生成应用程序的 .NET Framework 版本:
Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName);