You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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%缩放比例下,两个版本外观基本一致:
    100%缩放对比图

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

测试项目代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 04:45:55