这非常离奇。我移植了一个在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"); }
}
}
}
答案 0 :(得分:4)
BitmapFrame是一个来自PresentationCore程序集的类,总是在WPF应用程序中使用。它有一个模块初始化程序,可以自动生成程序dpiAware。 dpiAware对于WPF应用非常重要。对于Winforms应用程序应该be a feature,但必须手动打开它。
C#语言不支持module initializers。它大致类似于静态构造函数,但在程序集加载时运行。程序集由即时编译器加载,这就是为什么看起来只是让语句存在差异并执行它并不重要。
因此,避免此问题的最佳方法是在创建第一个窗口之前确保您的应用是dpiAware 。按照链接了解如何修改清单。如果不希望成为dpiAware,在Winforms中编写dpiAware代码并不那么直观,那么你可以通过粘贴这段代码来禁用PresentationCore的功能:
[assembly:System.Windows.Media.DisableDpiAwareness]
这需要添加对WindowsBase的引用。你可以把它放在任何你喜欢的地方,AssemblyInfo.cs是一个非常合乎逻辑的地方。