How do I execute code AFTER a form has loaded?


Question

In .NET, Windows Forms have an event that fires before the Form is loaded (Form.Load), but there is no corresponding event that is fired AFTER the form has loaded. I would like to execute some logic after the form has loaded.

Can anyone advise on a solution?

2
117
10/20/2008 4:19:10 PM

Accepted Answer

You could use the "Shown" event: MSDN - Form.Shown

"The Shown event is only raised the first time a form is displayed; subsequently minimizing, maximizing, restoring, hiding, showing, or invalidating and repainting will not raise this event."

175
10/20/2008 4:59:27 PM

Exper Answer

I sometimes use (in Load)

this.BeginInvoke((MethodInvoker) delegate {
  // some code
});

or

this.BeginInvoke((MethodInvoker) this.SomeMethod);

(change "this" to your form variable if you are handling the event on an instance other than "this").

This pushes the invoke onto the windows-forms loop, so it gets processed when the form is processing the message queue.

[updated on request]

The Control.Invoke/Control.BeginInvoke methods are intended for use with threading, and are a mechanism to push work onto the UI thread. Normally this is used by worker threads etc. Control.Invoke does a synchronous call, where-as Control.BeginInvoke does an asynchronous call.

Normally, these would be used as:

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;
  });
}

It does this by pushing a message onto the windows message queue; the UI thread (at some point) de-queues the message, processes the delegate, and signals the worker that it completed... so far so good ;-p

OK; so what happens if we use Control.Invoke / Control.BeginInvoke on the UI thread? It copes... if you call Control.Invoke, it is sensible enough to know that blocking on the message queue would cause an immediate deadlock - so if you are already on the UI thread it simply runs the code immediately... so that doesn't help us...

But Control.BeginInvoke works differently: it always pushes work onto the queue, even it we are already on the UI thread. This makes a really simply way of saying "in a moment", but without the inconvenience of timers etc (which would still have to do the same thing anyway!).

45
10/20/2008 8:52:51 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon