.NET Framework 4.7.2与.NET 9文本DPI缩放差异原因及回退方案咨询
.NET Framework 4.7.2与.NET 9高DPI缩放文本显示差异问题
在对文本进行DPI缩放时,.NET Framework 4.7.2与.NET 9之间存在细微的外观差异。我制作了一个支持DPI感知的小型测试项目,可分别编译为两个版本进行对比:
100%缩放比例下,两个版本外观基本一致:

150%缩放比例下(右侧为.NET 9版本),文本显示出现明显差异:字母'O'更宽,整体字母高度更低,视觉上几乎像是使用了不同字体:

测试项目代码
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <System.Windows.Forms.ApplicationConfigurationSection> <add Key="DpiAwareness" value="SystemAware"/> <add key="EnableWindowsFormsHighDpiAutoResizing" value="true"/> </System.Windows.Forms.ApplicationConfigurationSection> </configuration>
app.manifest
<?xml version="1.0" encoding="utf-8"?> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <!-- UAC Manifest Options If you want to change the Windows User Account Control level replace the requestedExecutionLevel node with one of the following. <requestedExecutionLevel level="asInvoker" uiAccess="false" /> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> <requestedExecutionLevel level="highestAvailable" uiAccess="false" /> Specifying requestedExecutionLevel element will disable file and registry virtualization. Remove this element if your application requires this virtualization for backwards compatibility. --> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <application> <!-- A list of the Windows versions that this application has been tested on and is designed to work with. Uncomment the appropriate elements and Windows will automatically select the most compatible environment. --> <!-- Windows Vista --> <!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />--> <!-- Windows 7 --> <!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />--> <!-- Windows 8 --> <!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />--> <!-- Windows 8.1 --> <!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />--> <!-- Windows 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> </application> </compatibility> <!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. Makes the application long-path aware. --> <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware> </windowsSettings> </application> <!-- Enable themes for Windows common controls and dialogs (Windows XP and later) --> <!-- <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> --> </assembly>
Program.cs
using System; using System.Drawing; using System.Windows.Forms; namespace WinFormsApp1 { internal static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault( false ); #if NET Application.SetDefaultFont( new Font( "Microsoft Sans Serif", 8.25f ) ); Application.SetHighDpiMode( HighDpiMode.SystemAware ); #endif Application.Run( new Form1() ); } } }
Form1.Designer.cs
using System.Drawing; using System.Windows.Forms; namespace WinFormsApp1 { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { button1 = new Button(); SuspendLayout(); // // button1 // button1.Location = new Point( 48, 122 ); button1.Margin = new Padding( 4, 4, 4, 4 ); button1.Name = "button1"; button1.Size = new Size( 186, 66 ); button1.TabIndex = 0; button1.Text = "Open track"; button1.UseVisualStyleBackColor = true; // // Form1 // AutoScaleDimensions = new SizeF( 168F, 168F ); AutoScaleMode = AutoScaleMode.Dpi; ClientSize = new Size( 628, 352 ); Controls.Add( button1 ); Margin = new Padding( 4, 4, 4, 4 ); Name = "Form1"; Text = "Form1"; ResumeLayout( false ); } #endregion private Button button1; } }
问题
该行为变更导致我们的应用程序在迁移到.NET 9后,部分按钮在高DPI设置下文本无法适配。请问此变更的原因是什么?是否有办法恢复到旧行为?
内容的提问来源于stack exchange,提问作者Samuel Baillargeon
相关产品推荐
相关产品推荐

