C# 如何配置应用程序以在具有高 DPI 设置(例如 150%)的机器上正确运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13228185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to configure an app to run correctly on a machine with a high DPI setting (e.g. 150%)?
提问by Boris
I've created a simple Winforms application in C#. When I run the application on a machine with high DPI settings (e.g. 150%), the application gets scaled up. So far so good! But instead of rendering the fonts with a higher font size, all texts are just scaled up, too. That of course leads to very blurry text (on all controls like buttons etc.).
我用 C# 创建了一个简单的 Winforms 应用程序。当我在具有高 DPI 设置(例如 150%)的机器上运行应用程序时,应用程序会被放大。到现在为止还挺好!但不是用更大的字体大小来渲染字体,所有的文本也只是按比例放大。这当然会导致非常模糊的文本(在按钮等所有控件上)。
Shouldn't windows take care of rendering the texts correctly? For example my application's title bar is rendered crisp & clear.
窗口不应该负责正确渲染文本吗?例如,我的应用程序的标题栏呈现清晰明了。
采纳答案by Hans Passant
Once you go past 100% (or 125% with the "XP-style DPI scaling" checkbox ticked), Windows by default takes over the scaling of your UI. It does so by having your app render its output to a bitmap and drawing that bitmap to the screen. The rescaling of that bitmap makes the text inevitably look fuzzy. A feature called "DPI virtualization", it keeps old programs usable on high resolution monitors.
一旦超过 100%(或 125%,勾选“XP 风格 DPI 缩放”复选框),默认情况下 Windows 会接管 UI 的缩放。它通过让您的应用程序将其输出呈现为位图并将该位图绘制到屏幕来实现。该位图的重新缩放使文本不可避免地看起来模糊。一种称为“DPI 虚拟化”的功能,它使旧程序可以在高分辨率显示器上使用。
You have to explicitly let it know that you can handle higher DPI settings by adding the <dpiAware>element to your manifest. The MSDN page is herebut it isn't complete since it is omitting the UAC settings. Project + Add New Item, pick "Application Manifest File". Edit the manifest text or copy/paste this:
您必须明确地让它知道您可以通过将<dpiAware>元素添加到清单来处理更高的 DPI 设置。MSDN 页面在这里但它不完整,因为它省略了 UAC 设置。项目 + 添加新项目,选择“应用程序清单文件”。编辑清单文本或复制/粘贴:
<?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>
You can also pinvoke SetProcessDPIAware() in your Main() method, necessary for example if you deploy with ClickOnce:
您还可以在 Main() 方法中调用 SetProcessDPIAware(),例如,如果您使用 ClickOnce 进行部署,则是必需的:
[STAThread]
static void Main() {
if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // Edit as needed
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();
UPDATE, this common need is finally a bit easier if you use VS2015 Update 1 or higher. The added manifest already has the relevant directive, just remove the comments.
更新,如果您使用 VS2015 Update 1 或更高版本,这个常见的需求最终会更容易一些。添加的清单已经有相关指令,只需删除注释。
Keyword for search so I can find this post back: dpiAware
搜索关键字,以便我可以找到这篇文章:dpiAware
回答by shanthi_karthika
Applications can be developed in two different mode.
应用程序可以在两种不同的模式下开发。
The first one is to declare our application to be non-DPI-aware (not declaring anything will default to this). In this case the operating system will render our application under the expected 96 DPIand then will do to the bitmap scaling that we discussed before. The result will be a blurry looking application, but with a correct layout.
第一个是声明我们的应用程序是非 DPI 感知的(不声明任何内容将默认为这个)。在这种情况下,操作系统将在预期的 96 DPI下呈现我们的应用程序,然后将执行我们之前讨论的位图缩放。结果将是一个看起来模糊的应用程序,但具有正确的布局。
The second option is to declare the application as DPI-aware. In this case the OS will not do any scaling and will let your application render according to the original DPI of the screen. In case of a per-monitor-DPI environment, your application will be rendered with the highest DPI of all the screens, then this bitmap will be scaled down to the proper size for each monitor. Downscaling results in a better viewing experience than upscaling but you might still notice some fuzziness.
第二个选项是将应用程序声明为 DPI-aware。在这种情况下,操作系统不会进行任何缩放,而是让您的应用程序根据屏幕的原始 DPI 进行渲染。在每个显示器 DPI 环境的情况下,您的应用程序将以所有屏幕中最高的 DPI 呈现,然后此位图将缩小到每个显示器的适当大小。与放大相比,缩小可带来更好的观看体验,但您可能仍会注意到一些模糊之处。
If you want to avoid that, you must declare your application as per-monitor-DPI-aware. Then you must detect when your application is dragged across different monitors and render according to the DPI of the current one.
如果您想避免这种情况,您必须将您的应用程序声明为每监视器 DPI 感知。然后你必须检测你的应用程序何时被拖到不同的显示器上,并根据当前显示器的 DPI 进行渲染。
Declaring the DPI awareness is done in a manifest file.
声明 DPI 感知是在清单文件中完成的。
refer the following link stackoverflow
参考以下链接 stackoverflow
回答by Vasco Bonilla
None of these suggestions worked for me but, something happened after I removed the Form.Font = new... from the Form.Design.cs, the form started to re-scale properly, it works if the Font is defined in the constructor or not at all. Why? somebody else may be able to explained, I just can talk about the changed I made and took me a few minutes to figured out it was the root cause for the form I was working on. Hope it helps.
这些建议都不适合我,但是,在我Form.Font = new从 中删除...之后发生了一些事情Form.Design.cs,表单开始正确缩放,如果在构造函数中定义了字体,它就会起作用。为什么?其他人可能能够解释,我只是可以谈谈我所做的更改,并花了我几分钟的时间才弄清楚这是我正在处理的表单的根本原因。希望能帮助到你。
回答by Wollmich
Using .NET Framework 4.7 and Windows 10 Creators Update (1703) or newer you must do the following things to configure high DPI support for your Windows Form application:
使用 .NET Framework 4.7 和 Windows 10 Creators Update (1703) 或更高版本,您必须执行以下操作才能为 Windows 窗体应用程序配置高 DPI 支持:
Declare compatibility with Windows 10.
声明与 Windows 10 的兼容性。
To do this, add the following to your manifestfile:
为此,请将以下内容添加到您的manifest文件中:
<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
Enable per-monitor DPI awareness in the app.configfile.
在app.config文件中启用每个显示器的 DPI 感知。
Windows Forms introduces a new System.Windows.Forms.ApplicationConfigurationSectionelement to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.
Windows 窗体引入了一个新的System.Windows.Forms.ApplicationConfigurationSection元素,以支持从 .NET Framework 4.7 开始添加的新功能和自定义。要利用支持高 DPI 的新功能,请将以下内容添加到您的应用程序配置文件中。
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Important
重要的
In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file.
在 .NET Framework 的早期版本中,您使用清单来添加高 DPI 支持。不再推荐此方法,因为它会覆盖 app.config 文件中定义的设置。
Call the static EnableVisualStyles method.
调用静态 EnableVisualStyles 方法。
This should be the first method call in your application entry point. For example:
这应该是应用程序入口点中的第一个方法调用。例如:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
The advantage of this is the support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.
这样做的优点是支持动态 DPI 方案,其中用户在启动 Windows 窗体应用程序后更改 DPI 或比例因子。
回答by Aranxo
Since at least Visual Studio 2017 you just have to add a manifest file and uncomment this section:
至少从 Visual Studio 2017 开始,您只需要添加一个清单文件并取消注释此部分:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>

