表格加载后如何执行代码?

ade*_*825 121 .net c# events winforms

在.NET中,Windows窗体有一个在加载窗体之前触发的事件(Form.Load),但是在加载窗体后没有触发相应的事件.我想在表单加载后执行一些逻辑.

任何人都可以建议解决方案吗?

Mat*_*ing 184

您可以使用"已显示"事件:MSDN - Form.Shown

"只有在第一次显示表单时才会显示所显示的事件;随后最小化,最大化,恢复,隐藏,显示或无效以及重新绘制将不会引发此事件."

  • 对我来说,似乎所显示的处理程序在表单加载时执行...我错了吗? (10认同)
  • 你应该添加This.Refresh(); 在您的逻辑之前首先在Shown事件内部,它将保持并刷新表单以在逻辑开始运行之前完全加载 (9认同)
  • 老但金......是的,你错了.GUI无法运行并行任务,在执行另一个执行时,执行某些操作非常重要. (3认同)
  • 如果在Load事件处理程序中有一个调用Application.DoEvents()的代码,则会在Load事件处理程序完成执行之前触发Shown事件。这是因为Shown事件实际上是使用Form.BeginInvoke(ShownEvent)和DoEvents()放入消息队列的,它在加载完成之前将其触发。 (2认同)

Mar*_*ell 47

我有时使用(在加载中)

this.BeginInvoke((MethodInvoker) delegate {
  // some code
});
Run Code Online (Sandbox Code Playgroud)

要么

this.BeginInvoke((MethodInvoker) this.SomeMethod);
Run Code Online (Sandbox Code Playgroud)

(如果要在"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;
  });
}
Run Code Online (Sandbox Code Playgroud)

它通过将消息推送到Windows消息队列来完成此操作; UI线程(在某些时候)对消息进行排队,处理委托,并向工作人员发出信号表明它已完成......到目前为止一直很好;-p

好; 那么如果我们在U​​I线程上使用Control.Invoke/Control.BeginInvoke会发生什么呢?它应对......如果你调用Control.Invoke,知道阻塞消息队列会导致立即死锁是明智的 - 所以如果你已经在UI线程上它只是立即运行代码...所以对我们没有帮助......

但是Control.BeginInvoke的工作方式不同:它总是将工作推送到队列,即使我们已经在UI线程上.这是一种非常简单的说法"在一瞬间",但没有计时器等的不便(无论如何仍然必须做同样的事情!).

  • 好的Marc Gravell.袋子的另一招;) (2认同)

Ahm*_*bry 6

第一次它不会启动"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.
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我有同样的问题,并解决如下:

实际上我想显示消息并在2秒后自动关闭它.为此我必须生成(动态)简单表单和一个标签显示消息,停止消息1500毫秒,以便用户阅读它.并关闭动态创建的表单.显示的事件发生在加载事件之后.所以代码是

Form MessageForm = new Form();
MessageForm.Shown += (s, e1) => { 
    Thread t = new Thread(() => Thread.Sleep(1500)); 
    t.Start(); 
    t.Join(); 
    MessageForm.Close(); 
};
Run Code Online (Sandbox Code Playgroud)