Windows 10操作系统上的Windows窗体图形问题

7
当我在Windows 10中运行任何Windows Forms应用程序时,窗口内的图形似乎变形了:

Bad Image

在设计时,这种情况不会发生:

Good Image

有人经历过这种情况吗?

(请打开图片以获得更好的查看体验。)


1
你是否在Windows或程序本身中启用了一些辅助功能或缩放相关的设置? - cbr
2
我遇到了同样的问题,虽然这不是一个答案,但我认为这与DPI缩放有关。如果你有高分辨率的屏幕,可以通过编译后运行exe文件,右键单击,在兼容性中勾选禁用显示缩放来测试它。最终我使用了WPF,它不会出现同样的问题。 - SmithMart
1
如果这个应用只是给你自己使用,那就没问题了。但如果你想让别人也用的话,要记得如果他们的显示器分辨率很高,比如22英寸的1080分辨率屏幕,他们也会遇到同样的问题。不过公平地说,我还需要在很多应用程序中设置这个选项! - SmithMart
你还记得在加载应用程序时设置了什么吗? - Vinicius Gonçalves
1
我使用了发布的解决方案,适用于Windows 8.1,也可能适用于Windows 10。 - Reza Aghaei
显示剩余3条评论
1个回答

8

针对 .NET Framework >= 4.7 的更新答案

打开 app.config 并添加以下部分:

<System.Windows.Forms.ApplicationConfigurationSection>
    <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>

了解更多信息,请参见:Windows窗体中的高DPI支持

.NET Framework < 4.7

为解决此问题,您可以使用以下任一选项使应用程序具有DPI感知能力:

重要提示: 建议您通过应用程序清单设置进程默认的 DPI 感知能力,而不是使用 API 调用。

使用应用程序清单文件

要使应用程序具有DPI感知能力,可以向项目中添加一个应用程序清单文件。然后在 app.manifest 文件中删除与 DPI 感知相关的部分:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
 <windowsSettings>
   <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
 </windowsSettings>
</application>

接下来,在您的app.config文件中,添加EnableWindowsFormsHighDpiAutoResizing设置其值为true:

<appSettings>
  <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>

如需更多信息,请参阅Microsoft docs中的以下主题:

  • Windows上的高DPI桌面应用程序开发

SetProcessDPIAware API调用示例

您可以在显示主窗体之前使用SetProcessDPIAware()方法设置应用程序的dpi,以防止Windows缩放应用程序。此外,您还应检查Windows版本是否大于或等于Vista:

static class Program
{
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool SetProcessDPIAware();

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        if (Environment.OSVersion.Version.Major >= 6)
            SetProcessDPIAware();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        Application.Run(new Form1());
    }
}

注意事项

  1. 如上所述,建议您通过应用程序清单设置进程默认的 DPI 意识,而不是使用 API 调用。

  2. 在使用 API 调用之前,请阅读文档以了解支持的操作系统以及可能出现的竞争条件,如果 DLL 在初始化期间缓存 dpi 设置,则需要注意。此外,请记住,DLL 应接受主机进程的 dpi 设置,而不是 API 调用本身。

  3. 您可能会发现,.NET Core 3.0 中 WinForms 实现的DpiHelper 类很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接