Windows 表单 window 在我创建 WPF 时更改其大小 window

Windows Forms window changes its size when I create a WPF window

我有一个 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 表单 window更改其大小(减小其尺寸)。

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

这些是您可以使用的一些方法。设置window的宽高:

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)

对我有用...

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

他们确实留下了后门来禁用此行为。 Copy/paste 这段代码,最好放在你的 EXE 项目的 AssemblyInfo.cs 源文件中:

   [assembly: System.Windows.Media.DisableDpiAwareness]

但这当然不是真正的解决方法,现在始终为您的所有 windows 启用 DPI 虚拟化。通过在其清单中声明您的应用程序 dpi-aware 来取得成功,这样 PresentationCore 就不会搞砸了。但是由于不可避免的副作用,您现在会发现您需要修复 Winforms UI。它只能在您更改 Form.AutoScaleMode 属性 或做一些不明智的事情时变小,例如硬编码 window 大小。该属性是 Q&D 修复。

如其他回复所述,这是因为 DPI 意识。为那些使用 VB.NET:

的人关闭它的快速修复

打开app.manifest

然后取消注释这部分并将DPI感知设置为false:

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