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 开始的 .NET Framework 版本支持的所有高 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 窗体添加配置元素

新的 DPI 更改事件

从 .NET Framework 4.7 开始,三个新事件允许以编程方式处理动态 DPI 更改:

  • DpiChangedAfterParent:父控件或窗体的 DPI 更改事件发生后,以编程方式更改时控件的 DPI 设置时触发。
  • DpiChangedBeforeParent:父控件或窗体的 DPI 更改事件发生前,以编程方式更改时控件的 DPI 设置时触发。
  • DpiChanged:当前显示窗体的显示设备上的 DPI 设置更改时触发。

新的帮助程序方法和属性

.NET Framework 4.7 还添加了许多新的帮助程序方法和属性,这些方法和属性提供了有关 DPI 缩放的信息并允许执行 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);

另请参阅