我之前评论过我遇到了同样的问题,并已经解决。我在这里记录下我的更改,以供其他人参考。
正如上面所观察到的,每当在WinForms应用程序中使用Windows UI缩放并且Just In Time (JIT)编译器处理来自WPF库的任何内容时,这种行为似乎会发生。在我的情况下,进入包含打开WPF版本MessageBox代码的方法将引起此问题。
通常,Windows会为您处理基本缩放,将其渲染到屏幕外位图,然后放大绘制到屏幕上。但是,当WPF加载时,它似乎接管了这一功能,好像在对Windows说:“嘿...我处理这个...”。之后,Windows停止为您缩放WinForms,并且您最终得到1x比例版本和通常会混淆控件。不过,WPF部分正在处理自己的缩放,并且看起来很好。
因此,我解决问题的方法是告诉Windows我将处理WinForms缩放。要启用它,您必须将以下内容添加到应用程序清单中(dll清单被忽略):
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
如果已经存在,请取消注释以下部分:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
您可以添加一个清单文件:
右键单击应用程序项目 -> 添加 -> 新建项... -> 应用程序清单文件
然后在...
应用程序项目 -> 属性 -> 应用程序 -> 资源
确保“清单”设置为app.manifest
现在您可以找到该文件并将上述XML添加到根<asmv1:assembly>
元素中。
如果您使用默认的应用程序清单并添加了该元素,则可能看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</asmv1:assembly>
现在,当您启动WinForms应用程序时,您会注意到它的清晰度更高,因为它以高dpi渲染,而不是96dpi然后缩放以填充空间。
您可能会注意到许多图像已经缩小了!
在我的情况下,按钮、MenuStripItems和ToolStripItems没有按预期缩放。
我发现大多数控件都有一个可以重写的方法,如下所示:
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
base.ScaleControl(factor, specified);
}
这是在应用程序启动时调用的,从主窗体筛选控件。我的Windows设置为200%,我的主窗体缩放模式设置为DPI,并且所有窗体都以100%比例(96dpi)设计。我在第一次尝试解决问题时改变了所有继承缩放模式的内容,这就是对我有用的方法,如果你使用字体或无则会产生同样的效果,但我还没有尝试过。
当此方法被调用时,我的UI缩放为200%,因此factor
简单地是{2.0, 2.0},然后我用它来重新创建一个缩放的Image
在Button
中,并将每个MenuStrip
和ToolStrip
的Items
上ImageScalingSize
增加,因为它们不接收ScaleControl调用。如果您从未添加过上面的XML,则仍会调用此方法,但因素仅为{1.0,1.0},这并没有什么帮助。
请注意:如果您正在使用图像列表,则不要在DesignMode下动态设置图像,否则ImageList将取消设置,保存时什么都不会设置。
还要注意,因素是相对于当前的因素。您会注意到,如果将应用程序移动到不同的dpi监视器之间,您将获得2.0,然后是0.5,然后是2.0,然后是0.5等。
现在我的WinForms应用程序看起来非常清晰,可以调用WPF UI元素而不会发疯!哎呀!
希望这能对某些人有所帮助