创建一个DPI感知的应用程序

81
我有一个 C# 表单应用程序,当我更改显示器 DPI 时,所有控件都会移动。 我使用了代码 this.AutoScaleMode = AutoScaleMode.Dpi,但它没有解决这个问题。 有人有什么想法吗?

你也可以查看这篇博客,我认为它提供了关于这个主题的很好的信息:http://www.telerik.com/blogs/winforms-scaling-at-large-dpi-settings-is-it-even-possible- - checho
就我个人而言,在最新的Windows 10上,我更成功地采取了相反的方法:确保我的传统Windows Forms应用程序不知道DPI。这迫使Windows 10使用其winforms的默认缩放,这很完美。要从代码中进行测试,请SetProcessDpiAwareness(0)。 0 =在某些枚举中不知道 - 谷歌详细信息,需要从“shcore.dll”中导入DllImport。建议在app.manifest中执行此操作;我只是提到代码作为测试,以确保。 - ToolmakerSteve
我在一个C# Winforms应用程序中遇到了一个问题,应用窗口使用的DPI从96 DPI(缩放因子125%)的屏幕设置变为120 DPI(缩放因子100%),但只在运行可执行文件时发生-在VS2013 IDE中运行时没有出现该问题。附加调试器以查找更改发生的位置给出了无法重现的结果。通过调用SetProcessDpiAwareness(0)进行修复。 - SimonKravis
11个回答

-1

由于Winform应用程序表单可能包含控件和图像,允许系统调整您的窗口大小并不是一个解决方案,但如果您能够管理每个DPI分辨率一个表单,并使用适当缩放的图像...这不是一个好主意,因为随着屏幕尺寸的增长,字体大小会减小。

当使用不同的DPI分辨率时,系统会强制您的表单重新定义其控件的大小、位置和字体,但不包括图像。解决方案是在运行时加载时更改表单的DPI,以便一切都恢复到原始大小和位置。

这是一个可能的解决方案,我已经在一个纸牌游戏应用程序中测试过了,其中我有大约80个图像按钮、TabControl等。

在每个表单的form_Load事件中,添加此代码片段:

  Dim dpi As Graphics = Me.CreateGraphics
    Select Case dpi.DpiX
        Case 120
            '-- Do nothing if your app has been desigbned with 120 dpi
        Case Else
    '-- I use 125 AND NOT 120 because 120 is 25% more than 96
            Me.Font = New Font(Me.Font.FontFamily, Me.Font.Size * 125 / dpi.DpiX)
    End Select

此外,一个快速的技巧是在同一台电脑上测试不同分辨率,而无需重新启动:
从控制面板中更改分辨率。 不要重新启动!相反,关闭您的会话并使用相同的用户打开一个新会话。
还有一个注意事项:如果您在运行时设置控件的大小和位置,则应将相同的DPI因子(例如125 / Dpi.Dpix)应用于新坐标。因此,最好从application.startup事件设置一个DPIFactor全局变量。
最后但并非最不重要的:
请勿从原始分辨率以外的分辨率在Visual Studio中打开应用程序,否则所有控件都会随着每个表单的打开而移动和调整大小,没有回头路……
希望这可以帮助您,祝您编程愉快。

你有没有尝试使用AutoScaleMode.None,而不是将表单的DPI设置回96? - Victor Zakharov
5
在用户使用高清显示器时,这种方式就无法正常工作了,会导致内容无法阅读。这种方法本质上是禁用了高清支持。 - Steve Sheldon

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