这很奇怪。我移植了一个在VS2008下可以正常工作的项目,但是当我使用VS2017进行构建时,一行的存在会导致我的对话框调整大小-该代码甚至不需要运行,它只需要存在于执行该操作的子例程中即可。跑!
我已经创建了该程序的最简单版本,以展示这种行为。尝试在不同版本的Visual Studio下构建/运行。
我既希望解释为什么会发生这种情况,也希望能解决它。谢谢。
using System;
using System.IO;
using System.Windows.Forms;
using System.Windows.Media.Imaging; // Need reference to PresentationCore
namespace Test2017
{
public class MainDlg : Form
{
[STAThread]
static void Main() { Application.Run(new MainDlg()); }
public MainDlg()
{
SuspendLayout();
var button = new Button { Location = new System.Drawing.Point(7, 56), Size = new System.Drawing.Size(263, 23), Text = "Note size before and after clicking" };
button.Click += Button_Click;
ClientSize = new System.Drawing.Size(282, 253);
Controls.Add(button);
ResumeLayout(false);
PerformLayout();
}
private void Button_Click(object sender, EventArgs e)
{
if (DateTime.Today.Year != 1234) return; // This will always return
try
{
// The following is never executed - but its very presence causes the dialog to shrink when running under VS2017
BitmapFrame.Create((FileStream)null); // Was using this to get metadata - that part works ok
MessageBox.Show("Success");
}
catch { MessageBox.Show("Exception"); }
}
}
}
最佳答案
BitmapFrame是一个来自PresentationCore程序集的类,始终在WPF应用程序中使用。它具有一个模块初始化程序,可自动使该程序成为dpiAware。对于WPF应用程序而言,使用dpiAware非常重要。对于Winforms应用程序,应按be a feature键,但必须手动将其打开。
C#语言不支持module initializers。它大致类似于静态构造函数,但是在加载程序集时运行。程序集是由即时编译器加载的,这就是为什么看起来好像只有存在的语句才有所作为,而执行它并不重要。
因此,避免该问题的最佳方法是在创建第一个窗口之前,确保您的应用是dpiAware。单击链接以了解如何修改清单。如果不希望使用dpiAware,则在Winforms中编写dpiAware代码不是那么直观,那么您可以通过粘贴以下代码来禁用PresentationCore的功能:
[assembly:System.Windows.Media.DisableDpiAwareness]
这需要添加对WindowsBase的引用。您可以将其放在任何喜欢的位置,AssemblyInfo.cs是一个很合逻辑的地方。