如何使.NET 6 Windows Forms忽略DPI缩放?

问题描述 投票:0回答:3

我正在使用 Windows 窗体通过 SharpDX 托管 DirectX 渲染的内容

RenderForm
。问题是,当我设置表单
Size
时,它会根据显示器的缩放因子对其进行缩放,这不是我需要的,因为我进行基于像素的渲染。

我尝试将表单的

AutoScaleMode
设置为
None
,但似乎没有效果。

我还玩过

DpiAwareness
中的
System.Windows.Forms.ApplicationConfigurationSection
以及应用程序清单中的相应设置。

我的目标是以像素为单位完成所有事情。

winforms dpi highdpi
3个回答
1
投票

我也有同样的问题。

我有一个.Net6.0项目,其中有很多继承自现有控件或定制控件的控件。

以下是我发现的。

  1. Application.SetHighDpiMode(HighDpiMode.PerMonitorV2)
    对我的项目没有帮助。控件仍根据 DPI 缩放调整大小。

  2. Application.SetHighDpiMode(HighDpiMode.DpiUnaware)
    可以阻止你的 winform 进行 DPI 缩放。但效果图太模糊,客户无法接受

  3. 更改app.config中的配置是没有用的。在.Net 6.0中,在app.config中添加以下配置会导致ConfigurationErrorsException。

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

经过长时间的研究,我终于找到了在.NET 6.0 for Winforms中忽略DPI缩放的解决方案:

  1. 所有表单和控件的 AutoScaleMode 设置为 None。

  2. 不要使用点来设置字体大小,而是使用像素。如果您以 Point 指定字体大小,它将根据您的 DPI 设置进行放大。缩放很丑陋,因为您的控件可能无法按字体大小的比例缩放,从而使单词太大而无法适应控件(例如按钮或数据网格视图)。相比之下,如果您以像素为单位指定字体大小,则文字不会根据您的 DPI 设置进行缩放。

  3. 作为一种良好的做法,使用布局控件(例如表格布局、流动布局)、填充和边距来定位控件。尽管您的控件无法缩放,但您的主窗口可以缩放。这些为您提供控件之间的相对定位,一旦用户调整窗口大小,就会触发自动定位。


0
投票

此行在创建对我有用的主表单之前运行:

Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);

原因是,通过显式声明缩放意识,您可以选择退出 Windows 窗体,通过隐式乘以所有大小来为您处理缩放。

AutoScaleMode
结果是不需要的。

根据

SetHighDpiMode
文档,清单方法也应该有效,但我怀疑在从 JetBrains Rider 启动项目时,有些侥幸阻止了它被采用。


0
投票

Winform、.NET 4.7.2、 程序.cs

[DllImport("user32.dll", EntryPoint = "SetProcessDPIAware")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetProcessDPIAware();
 
SetProcessDPIAware();

form.cs

   //SharpDX
   scaleFactor = GetDpiForSystem() / 96.0f;
   Console.WriteLine(scaleFactor);
   //float scaleFactor = 1.25f;
   var targetProperties = new HwndRenderTargetProperties {
       Hwnd = this.Handle,
       //PixelSize = new Size2(this.Bounds.Right - this.Bounds.Left, this.Bounds.Bottom - this.Bounds.Top),
       PixelSize = new Size2((int)(screenWidth * scaleFactor), (int)(screenHeight * scaleFactor)),
       PresentOptions = PresentOptions.Immediately
   };

但是会模糊。

如果我使用this.BackgroundImage = fullScreenCapture();,就没有问题。但是当使用 SharpDX 时,禁用 DPI 缩放似乎没有效果: windowRenderTarget.DrawBitmap(fullScreenCapture(), 1.0f, BitmapInterpolationMode.Linear);我不知道为什么。

© www.soinside.com 2019 - 2024. All rights reserved.