Where is Form's Loaded event?

Wow, it’s been a while since I last posted something here. We’ve recently moved to BC so I’ve been pretty distracted. I hope to be able to post more regularly in the coming weeks.

This is a bit off-topic for me but here goes.

Recently I needed to run some code right after a form is displayed for the first time. The Form.Load event is handy for performing various tasks when a form is loading but before it is displayed for the first time. Unfortunately there is no corresponding Form.Loaded event to notify the application that the form has actually loaded and is visible.

Fortunately it’s quite easy to pull it off without resorting to the WaitForInputIdle function. All you need to do is override Form’s OnLoad method and add an event handler for the Application.Idle event. Since we only want to be notified a single time that the form is loaded, we immediately remove the delegate in the event handler. You can of course register the event handler earlier in the form or application’s lifetime but I prefer to keep delegates registered for as short a period as possible.

Here’s a simple example:

protected override void OnLoad(EventArgs args)
{
    base.OnLoad(args);

    Application.Idle += new EventHandler(OnLoaded);
}

private void OnLoaded(object sender,
                      EventArgs args)
{
    Application.Idle -= new EventHandler(OnLoaded);

    // TODO: add relevant code here
}

This might be useful, for example, if you need to prompt the user (the horror!) for something but would prefer the dialog box to appear in the context of your application’s main window.


© 2004 Kenny Kerr

5 Comments

  • ...I prefer to keep delegates registered for as short a period as possible...



    Why?

    Thanks.

  • Tom, it’s all about avoiding surprises. Delegates and events make it easy to complicate your programs with asynchronous method calls. It’s very easy to register for an event and forget to un-register, especially in Windows Forms applications. It’s about writing robust applications. Same reason you declare variables close to where they are needed and initialize them at declaration time. Avoid surprises.

  • Tero, BeginInvoke is not quite the same thing. I wanted to make sure the OnLoaded method is called when the application is idle; indicating the message queue is empty. BeginInvoke is loosely equivalent to the PostMessage function which places a message in the message queue to be handled by the window procedure. So it’s possible that the event handler used with BeginInvoke will be called sooner than you expect and possibly before the window is actually visible.

  • Nice solution to a common problem.

    The old trick using the Form.Activate event coupled with a switch isnt as robust as the proposed solution....

  • Thanks Kenny, works great!

Comments have been disabled for this content.