Я написал этот пример программы - упрощение очень сложного приложения.Тот же двоичный файл [.exe] выдает исключение нулевого указателя на некоторых машинах при запуске.Итак, я хочу знать, как правильно создать форму Windows Forms.
В нашем приложении метод Form1_SizeChanged
является результатом метода this.ResumeLayout(false)
, который является последним оператором в InitializeComponents()
.Я не знаю, чтобы это смоделировать, поэтому я сам изменил размер для этой тестовой программы.
public partial class Form1 : Form
{
public class Logger {
public Logger() { }
public void log(string str) {
Console.WriteLine("logging - " + str);
}
}
Logger logger = null;
public Form1()
{
InitializeComponent();
this.Size = new Size(200, 300);
MyInitialize();
}
private void MyInitialize() {
// Just that it takes some time.
Console.WriteLine("MyInitialize -- Enter");
for (int count = 0; count <5 ; count++){
Console.WriteLine("Sleeping -- " + count);
Thread.Sleep(1000);
}
logger = new Logger();
}
private void sleepingPill(int millisec) {
Thread.Sleep(millisec);
}
private void Form1_SizeChanged(object sender, EventArgs e)
{
logger.log("Form1_SizeChanged -- Enter");
}
}
В соответствии с моим пониманием, Form1_SizeChanged
не следует вызывать, если Form1
не будет правильно построен.Может кто-нибудь пролить свет на то, как работает архитектура событий Windows Forms в этом сценарии?
Original Stack Trace: from our complex application
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=ABCD
StackTrace:
at ABCD.Form1.AppendToLog(String s)
at ABCD.Form1.Form1_SizeChanged(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnSizeChanged(EventArgs e)
at System.Windows.Forms.Control.UpdateBounds(Int32 x, Int32 y, Int32 width, Int32 height, Int32 clientWidth, Int32 clientHeight)
at System.Windows.Forms.Control.UpdateBounds(Int32 x, Int32 y, Int32 width, Int32 height)
at System.Windows.Forms.Control.SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified)
at System.Windows.Forms.Form.SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified)
at System.Windows.Forms.Control.ScaleControl(SizeF factor, BoundsSpecified specified)
at System.Windows.Forms.ScrollableControl.ScaleControl(SizeF factor, BoundsSpecified specified)
at System.Windows.Forms.Form.ScaleControl(SizeF factor, BoundsSpecified specified)
at System.Windows.Forms.Control.ScaleControl(SizeF includedFactor, SizeF excludedFactor, Control requestingControl)
at System.Windows.Forms.ContainerControl.Scale(SizeF includedFactor, SizeF excludedFactor, Control requestingControl)
at System.Windows.Forms.ContainerControl.PerformAutoScale(Boolean includedBounds, Boolean excludedBounds)
at System.Windows.Forms.ContainerControl.PerformNeededAutoScaleOnLayout()
at System.Windows.Forms.ContainerControl.OnLayoutResuming(Boolean performLayout)
at System.Windows.Forms.Control.ResumeLayout(Boolean performLayout)
at ABCD.Form1.InitializeComponent()
at ABCD.Form1..ctor()
at ABCD.Program.Main()
InnerException:
Уведомление из трассировки стека: Form1_sizeChanged вызывается из InitializeComponents () .., который, я думаю, не должен происходить.Form1_sizeChanged является методом экземпляра класса Form1 и не должен вызываться перед созданием Form1.Если среда .NET хочет обработать это событие, она должна подождать, пока форма Form1 будет построена правильно, не так ли?