1

我的任务是为针对 .NET 4.7.2 的旧版 WinForms 应用程序添加对 Per-Monitor V2 DPI 感知的支持。我知道这是一个复杂的问题,我在 StackOverflow 和 MSDN 上阅读了很多关于这个主题的内容。使用测试项目,我已经掌握了基础知识。测试应用程序会随着 DPI 的变化而重新调整。

这是我的问题:旧版软件在每个表单上都包含许多自定义字体(不同的样式和大小),当 DPI 在运行时发生变化时,我无法让这些字体重新缩放。看来我可以在表单上设置我喜欢的任何字体,如果我AutoScaleMode.Dpi在表单上使用它会正确重新缩放。但是,一旦我在子控件上设置了自定义字体,就不会对该控件应用重新缩放。随着 DPI 的变化,大小保持不变。如果 DPI 不变,这不是问题。仅当在具有不同 DPI 设置的监视器之间移动或在运行时更改监视器的 DPI 设置时才会出现此问题。(注:所有字体更改发生在设计器中)

这是一个例子:

显示器 1 - 96 DPI

显示器 1 - 96 DPI

显示器 2 - 144 DPI

显示器 2 - 144 DPI

您可以看到它checkBox3是粗体并且在 96 DPI 时正确缩放。但是,当我将应用程序拖到监视器 2 时,checkbox3它仍然未缩放,因此现在它比其他文本小。

重新缩放的损失对我来说确实有点意义,因为在子控件上设置自定义字体会破坏环境字体关系。根据我的测试,当 DPI 发生变化时,表单实际上会获得具有新 DPI 缩放点大小的新字体。没有更新不使用该字体的控件是有道理的。但是有没有办法要求所有控件重新调整自己的比例?

我一直试图在上述测试项目(C# .NET 4.7.2)中解决这个问题。我发现重新调整自定义字体的唯一方法是在 DPI 更改时使用 DPI 更改事件手动重新创建自定义字体。

private void CheckBox3_DpiChangedAfterParent(object sender, EventArgs e)
{
    checkBox3.Font = new Font(Font.FontFamily, 
                              checkBox3.Font.SizeInPoints * _dpiScaleFactor, 
                              checkBox3.Font.Style);
}

private void Form1_DpiChanged(object sender, DpiChangedEventArgs e)
{
   _dpiScaleFactor = (float)e.DeviceDpiNew / e.DeviceDpiOld;
}

显示器 2 - 144 DPI(手动调整字体大小)

显示器 2 - 144 DPI(手动调整字体大小)

所以这似乎确实有效。当然,还有更好的方法。我在这里想念什么?

4

0 回答 0