当我创建 WPF 窗口时,Windows 窗体窗口会更改其大小
Posted
技术标签:
【中文标题】当我创建 WPF 窗口时,Windows 窗体窗口会更改其大小【英文标题】:Windows Forms window changes its size when I create a WPF window 【发布时间】:2015-11-21 10:58:39 【问题描述】:我有一个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 窗体窗口时会更改其大小(减小其尺寸)。
这怎么可能?如何避免这种行为?
【问题讨论】:
两台电脑的 DPI 一样吗? 这与 DPI 有关。当您第一次使用 WPF 中的程序集时,Windows 窗体应用程序会随机调整大小。我的猜测是您需要在清单中声明应用程序不支持 DPI。 @AnkurTripathi 实际上这些计算具有不同的 DPI,将两者都设置为 100% 可以使应用程序正常工作。但是如何在不更改 DPI 的情况下避免这种行为? @ghord 该应用程序是一个 WinForms 应用程序,我在哪里设置它不是 DPI 感知的精确度?怎么样? 你必须根据 DPI 设置每个宽度和高度等我写一些代码给你.. 【参考方案1】:您发现 WPF 调用 SetProcessDPIAware()。它发生在 PresentationCore 的模块初始化程序中。这在形式上是非法的,必须始终在应用程序创建任何可能缓存 DPI 值的窗口或加载 DLL 之前调用它。或者换句话说,这可能会出错的很多方法,你还只是发现了它的温和版本。在纯 WPF 应用程序中通常不会出现问题,因为在创建任何窗口之前总是需要加载 PresentationCore。
他们确实留下了一个后门来禁用这种行为。复制/粘贴此代码,最好在您的 EXE 项目的 AssemblyInfo.cs 源文件中:
[assembly: System.Windows.Media.DisableDpiAwareness]
但这当然不是真正的解决方案,DPI 虚拟化现在始终为您的所有窗口启用。通过在其清单中声明您的应用程序 dpi-aware 来取得成功,这样 PresentationCore 就不会搞砸了。但是由于不可避免的副作用,您现在会发现需要修复 Winforms UI。只有当您更改 Form.AutoScaleMode 属性或执行一些不明智的操作(如硬编码窗口大小)时,它才会变小。该属性是 Q&D 修复。
【讨论】:
【参考方案2】:正如其他回复中所述,这是由于DPI 意识。为使用 VB.NET 的用户关闭它的快速修复:
打开app.manifest
然后取消注释这部分并将DPI感知设置为false:
请注意,这可能会导致您的应用程序的字体在更高 DPI 设备上看起来更模糊。
【讨论】:
【参考方案3】:这些是您可以使用的一些方法。设置窗口的宽高:
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)
它对我有用...
【讨论】:
宽高是Form属性吗?我应该什么时候设置它们?一旦启动? 是的,宽度和高度是表单属性..,,,, 并且可以在窗口的加载方法 this.Loaded += Window_Loaded(); 它对我不起作用,无论是使用 GetDIPIndependent 还是 GetDIPDependent... DPI 设置为 150% 的计算机上的窗口仍会自行调整大小。 如果计算机是 100% 并且您想设置宽度 800 而不是看起来像 800 ...但是如果计算机是 150% 您想设置宽度 800 而不是看起来像 512 (DIPDependent) 告诉我您设置宽度和高度的代码,并可以显示图像发生了什么.. 我在 InitializeComponent() 之后设置了宽度和高度(代码与我的问题相同)以上是关于当我创建 WPF 窗口时,Windows 窗体窗口会更改其大小的主要内容,如果未能解决你的问题,请参考以下文章
如何在鼠标位置打开具有 Windows 窗体父级的 WPF 窗口?