在我创建WPF窗口时,Windows窗体窗口会更改其大小

我有一个System.Window.Forms.Form ,我处理每个按钮点击。 当我收到第一个事件时,我创建了一个新的WPF System.Windows.Window对象。

 class WPF_Window : Window { } public partial class Form1 : Form { WPF_Window wnd = null; public Form1() { InitializeComponent(); } private void Form1_MouseClick(object sender, MouseEventArgs e) { if (wnd == null) { wnd = new WPF_Window(); } } } 

在我的计算机上,此代码按预期工作,但如果我在另一台计算机(Windows 10)上运行它,当我单击Windows窗体窗口时更改其大小(减小其尺寸)。

这怎么可能? 我怎样才能避免这种行为?

您发现WPF调用SetProcessDPIAware()。 它发生在PresentationCore的模块初始化程序中。 这在forms上是非法的,必须始终在应用创建任何窗口或加载可能缓存DPI值的DLL之前调用它。 换句话说,很多方法可能会出错,你只是发现它的温和版本。 在纯WPF应用程序中通常不会出现问题,因为在创建任何窗口之前总是需要加载PresentationCore。

他们确实留下了一个后门来禁用这种行为。 复制/粘贴此代码,最好在EXE项目的AssemblyInfo.cs源文件中:

  [assembly: System.Windows.Media.DisableDpiAwareness] 

但这当然不是一个真正的解决方案,现在总是为所有窗口启用DPI虚拟化。 通过在其清单中声明您的app dpi-aware来获得提升,以便PresentationCore不会搞砸它。 但是,由于不可避免的副作用,您现在将发现需要修复Winforms UI。 它只能在您更改Form.AutoScaleMode属性时变小,或者像硬编码窗口大小那样做一些不明智的事情。 该属性是Q&D修复。

正如其他回复所述,这是因为DPI意识 。 一个快速解决方案,为使用VB.NET的人关闭它:

打开app.manifest

在此输入图像描述

然后取消注释此部分并将DPI意识设置为false

在此输入图像描述

请注意,这可能会导致应用程序的字体在较高DPI设备上看起来更模糊。

这些是您可以使用的方法。 设置窗口的宽度和高度:

 public static Graphics graphics = Graphics.FromHwnd(IntPtr.Zero); public static double GetDIPIndependent(double value, double DPI) { value = value * (graphics.DpiX / DPI); return value; } public static double GetDIPDependent(double value, double DPI) { value = value * (DPI / graphics.DpiX); return value; } public static double GetDIPIndependent(double value) { value = value * (graphics.DpiX / 96.0); return value; } public static double GetDIPDependent(double value) { value = value * (96.0 / graphics.DpiX); return value; } 

例:

如果DPI独立

 this.Width = GetDIPIndependent(this.Width) this.Height = GetDIPIndependent(this.Height) 

如果DPI依赖

 this.Width = GetDIPDependent(this.Width) this.Height = GetDIPDependent(this.Height) 

这个对我有用…