C#缩放UserControl内容以匹配用户Dpi /字体大小

如何让OwnerDrawn UserControl尊重用户dpi(96/120 / xxx)和/或font-size(普通,大,超大)?

有些人建议在Graphics对象上使用DpiX和DpiY属性,但这似乎对我控制中的任何东西都没有(即它们总是设置为96,无论我选择哪种字体大小或dpi)。

StackOverflow上还有另一个类似的问题,它建议使用AutoScale属性,但建议的解决方案也没有做任何事情。

除了依赖WPF之外,在.NET中没有办法做到这一点吗?

您需要将UserControl的AutoScaleMode属性设置为AutoScaleMode.Dpi,而不是将AutoScale属性设置为true。 如果这样做,它会将AutoScaleMode重置为None。 AutoScale属性已过时,仅用于向后兼容(请参阅本MSDN文章中的重要说明 )。

此外,在Windows Vista / 7中,除非您明确指定应用程序支持DPI,否则Windows将模拟默认DPI环境,以便应用程序使用96 DPI进行渲染,然后将生成的位图缩放到适当的大小。 为避免这种情况,您可以更改应用程序清单以通知Windows您确实知道DPI – 请参阅本文中的使用清单声明DPI感知部分。

我有同样的问题,我尝试使用GetDC + GetDeviceCaps + ReleaseDC,除了使用Graphics工作,至少在Vista32上。 我对DPI没有经验,但是没有人回答这个问题,至少这对其他人有帮助。

查看创建DPI感知应用程序 。 这提到为什么它可能总是返回96,无论实际的DPI设置如何。

从上面链接引用:

Win32应用程序中的DPI扩展

在Win32应用程序中,执行以下操作:

  • 使用SetProcessDPIAware函数取消dpi缩放。
  • 在确定绘制的界面元素大小时,请使用物理测量,例如厘米。 通过使用物理尺寸而不是像素,可以确保在所有类型的显示器上保持一致的尺寸。
  • 要获得系统dpi设置,请使用带有LOGPIXELSX标志的CDC :: GetDeviceCaps函数。 如果不取消dpi缩放,则此调用将返回默认值96 dpi。
  • 使用GetSystemMetrics函数获取用户界面元素的首选大小,例如窗口边框。 禁用dpi缩放时,为界面元素返回的测量值将缩放为所选的dpi设置。 如果dpi缩放处于活动状态,则无论系统dpi设置如何,该函数都会根据96 dpi返回测量值。

回答: 关于DPI问题

使用 -statement( 原始源 )重写的示例代码:

float dpiX = 96, dpiY = 96; using(Graphics graphics = this.CreateGraphics()) { dpiX = graphics.DpiX; dpiY = graphics.DpiY; }