【问题标题】:Why is a winform shown different on the same 4k monitor为什么winform在同一个4k显示器上显示不同
【发布时间】:2017-08-29 06:22:59
【问题描述】:

我们有一个旧版 .net windows 窗体应用程序。 我们已经将其中大部分替换为 Web 应用程序,但仍使用 Windows 窗体应用程序来执行管理任务。

在 4k 显示器上使用此应用程序时,它看起来非常糟糕,这是可以理解的。

但外观会根据系统上的其他显示器而变化。 测试是在 lenovo 430 上完成的,该 430 具有通过显示端口连接的 4k 显示器。 笔记本电脑显示器的分辨率为 1920/1080,4k 显示器的分辨率为 3840/2160。显示比例始终为 200%。

以下所有屏幕截图均在 4k 显示器上拍摄。

  1. 一个测试,两个监视器都处于活动状态
  2. 仅使用第二个屏幕进行一次测试
  3. 关闭笔记本电脑显示器的测试(这意味着系统只有一个显示器可用)

我知道如果不进行更改和设置 dpiAware/dpiAwareness,我们的应用程序在 4k 上看起来会不太好。

但我的问题是: 为什么应用程序的外观仅取决于哪些监视器处于活动状态?有没有办法控制采取哪种“类型”的外观?

【问题讨论】:

  • 据我所知,发生这种情况的部分原因是您如何设置 winform 的布局属性。例如,如果将AutoSize 设置为True,则监视器分辨率的每次更改都会影响表单大小。 Anchor & Dock 也是如此,这就是为什么大多数人更喜欢 WPF 而不是 Winforms。如果不正确设置此属性,从 3840/2160 到 1920/1080 监视器,您会得到一个“抽象”(试图在这里开玩笑)winform。

标签: c# winforms


【解决方案1】:

也许你知道这一点,但之前没有提到:

有3种应用:

  • 不支持 DPI
  • 系统 DPI 感知
  • 每显示器 DPI 感知

这里的详细信息: https://msdn.microsoft.com/de-de/library/windows/desktop/dn469266(v=vs.85).aspx

您可以在 app.config 中为您的应用设置 DPI 感知:

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

和 app.manifest:

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

当您的 DPI >= 150% 时,还可以通过以下方式控制缩放 人民币应用 -> 属性 -> 兼容性 -> 高 DPI 缩放

对于 Windows 窗体,默认设置是禁用高 DPI 的 DPI 缩放。所以一切都应该开箱即用。也许其中一项设置不是默认设置?尤其是exe上的RMB属性中的配置?

【讨论】:

  • " 对您有用吗?在 4.7.2 中,我仍然会自动调整大小
【解决方案2】:

Microsoft 已意识到此问题并使用 .Net 4.7 Framework 修复了该问题:

https://blogs.msdn.microsoft.com/dotnet/2017/04/05/announcing-the-net-framework-4-7/

【讨论】:

  • 来自 4.7 版本说明:“此版本包括大量针对 Windows 窗体 DPI 感知应用程序的高 DPI 改进”。但我的例子根本不是 DPI Aware。它只是看起来不同,具体取决于秒屏幕。无论如何我都会用 4.7 测试它。
  • 我认为发行说明中最重要的一句话是 Windows 窗体基于光栅图形,我个人认为在您的情况下,200% 的缩放在应用程序更改的原因中起着重要作用在不同的显示器内。但这仍然是一个猜测。
【解决方案3】:

在我的特定情况下,我遇到缩放问题的应用程序正在为 WinForms 和 WPF 使用 DevExpress 组件(同时)。我在 DevExpress 的网站上使用 instruction 解决了 4K 显示器的缩放问题。在我看来,这条指令是相当笼统的,而不是特定于 DevExpress 的东西。

也就是说,我只是添加了 app.manifest 文件并将其默认内容替换为以下内容:

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
    <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">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</assembly>

您可以通过右键单击项目并选择 Add New Item 来添加 app.manifeset 文件:

希望对你也有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 2014-11-24
    • 2020-04-28
    相关资源
    最近更新 更多