在.NET中,Windows窗体有一个在加载窗体之前触发的事件(Form.Load),但是在加载窗体后没有触发相应的事件.我想在表单加载后执行一些逻辑.
任何人都可以建议解决方案吗?
您可以使用"已显示"事件:MSDN - Form.Shown
"只有在第一次显示表单时才会显示所显示的事件;随后最小化,最大化,恢复,隐藏,显示或无效以及重新绘制将不会引发此事件."
我有时使用(在加载中)
this.BeginInvoke((MethodInvoker) delegate { // some code });
要么
this.BeginInvoke((MethodInvoker) this.SomeMethod);
(如果要在"this"以外的实例上处理事件,请将"this"更改为表单变量).
这会将调用推送到windows-forms循环,因此在表单处理消息队列时会对其进行处理.
[根据要求更新]
Control.Invoke/Control.BeginInvoke方法旨在与线程一起使用,并且是将工作推送到UI线程的机制.通常,这由工作线程等使用.Control.Invoke执行同步调用,其中 - 当Control.BeginInvoke执行异步调用时.
通常,这些将用作:
SomeCodeOrEventHandlerOnAWorkerThread() { // this code running on a worker thread... string newText = ExpensiveMethod(); // perhaps a DB/web call // now ask the UI thread to update itself this.Invoke((MethodInvoker) delegate { // this code runs on the UI thread! this.Text = newText; }); }
它通过将消息推送到Windows消息队列来完成此操作; UI线程(在某些时候)对消息进行排队,处理委托,并向工作人员发出信号表明它已完成......到目前为止一直很好;-p
好; 那么如果我们在UI线程上使用Control.Invoke/Control.BeginInvoke会发生什么呢?它应对......如果你调用Control.Invoke,知道阻塞消息队列会导致立即死锁是明智的 - 所以如果你已经在UI线程上它只是立即运行代码...所以对我们没有帮助......
但是Control.BeginInvoke的工作方式不同:它总是将工作推送到队列,即使我们已经在UI线程上.这是一种非常简单的说法"在一瞬间",但没有计时器等的不便(无论如何仍然必须做同样的事情!).
第一次它不会启动"AfterLoading",
它只会注册它以启动NEXT Load.
private void Main_Load(object sender, System.EventArgs e) { //Register it to Start in Load //Starting from the Next time. this.Activated += AfterLoading; } private void AfterLoading(object sender, EventArgs e) { this.Activated -= AfterLoading; //Write your code here. }
我有同样的问题,并解决如下:
实际上我想显示消息并在2秒后自动关闭它.为此我必须生成(动态)简单表单和一个标签显示消息,停止消息1500毫秒,以便用户阅读它.并关闭动态创建的表单.显示的事件发生在加载事件之后.所以代码是
Form MessageForm = new Form(); MessageForm.Shown += (s, e1) => { Thread t = new Thread(() => Thread.Sleep(1500)); t.Start(); t.Join(); MessageForm.Close(); };