10

I am working on a C# WinForm application.

I want to trigger some processing once the form has been "shown" and the layout of the form is complete.

I am using the "_Shown" event, but this seems to trigger before the layout of the form has completed. Is there event I can use that fires once the layout is complete?

BENBUN Coder
  • 4,801
  • 7
  • 52
  • 89
  • Remember that every time you change a controls size the Layout event fires. This include changing the text of a autosize control like a Label. – monkey_p Jan 05 '10 at 10:50
  • 2
    Can you post your solution with the delay timer when you get it to work? , cause it sounds interesting . – Madi D. Jan 05 '10 at 11:11

7 Answers7

20

Put Application.DoEvents() at the start of the form's Shown event handler. This will force all the controls to be rendered.

MikeM
  • 201
  • 2
  • 2
6

I don't see an event after Shown you can use for this purpose. Could you not use a timer to delay your processing in the Shown event?

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • This is what I opted for in the end - feels like a bit of a hack, but it works. – BENBUN Coder Jan 05 '10 at 10:56
  • 1
    Actually , GotFocus is called after the Shown event, however using a delay timer is a nice hack, can u post the solution when your done? i'm highly interested. – Madi D. Jan 05 '10 at 11:10
3

An old trick in VB6 used to be to use the Paint event:

bool firstShown = false;

void form_Paint(Object sender, EventArgs e) {
  if ( !firstShown ) {
    YourMethodThatNeedsToRunOnShown();
    firstShown = true;
  }

  //the rest of your paint method (if any)

}

It is a little hacky, but it does work

Pondidum
  • 11,457
  • 8
  • 50
  • 69
2

This works for me and is much less "hacky" than other suggestions:

protected override void OnLayout(LayoutEventArgs levent)
{
    base.OnLayout(levent);

     if(someControl == null)
       return; // be careful of OnLayout being called multiple times

    // otherwise, do some stuff here, set control sizes, etc.
}
znelson
  • 919
  • 1
  • 10
  • 24
  • The problem with this approach is if the "stuff" takes significant time (noticeably blocks OnLayout), then the form is visible in an incomplete state until OnLayout returns. In my case, my "stuff" pops a dialog and spawns a BackgroundWorker to do the processing; the dialog blocks OnLoad and the form looks ugly until it completes. I think the timer approach is going to be my best bet as well. – Brian A. Henning Apr 28 '20 at 16:38
1

AS far as I can remember the event order is something like

Form.Load
Form.Layout 
Form.VisibleChanged
Form.GotFocus
Form.Activated
Form.Shown

So if something is still happening after Form.Show it's because of the way you coded it.

Are you maybe creating the form dynamically?

monkey_p
  • 2,849
  • 2
  • 19
  • 16
1

The best solution is the Shown() event: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.shown.aspx

"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."

JS5
  • 729
  • 7
  • 17
0

Try using Form.GotFocus (inherited from control).. something like this.

   private void Form1_Load(object sender, EventArgs e)
    {
        this.GotFocus += new EventHandler(Form1_gotFocus);
        this.Focus();
    }

    private void Form1_gotFocus(object sender, EventArgs e)
    {
      // You will need to Switch focus from form at the end of this function, 
      //to make sure it doesnt keep Firing.
    }

According To msdn , the following happens:

When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ContainerControl..::.ActiveControl property to the current form, focus events occur in the following order:

  1. Enter
  2. GotFocus
  3. Leave
  4. Validating
  5. Validated
  6. LostFocus
Madi D.
  • 1,980
  • 5
  • 23
  • 44
  • This looks likes a good approach, but unfortunately the event does not trigger when the form is shown. Code is as per http://codepaste.net/j6wdbg – BENBUN Coder Jan 05 '10 at 10:29
  • Add a Form.Focus = true on form load, i will edit my code to add that :) – Madi D. Jan 05 '10 at 10:47
  • The reason the GotFocus event doesn't fire is because the TextBox has the focus. – monkey_p Jan 05 '10 at 10:52
  • Correct me if i am wrong but if u force this.Focus() , wouldn't that force the Focus on the form, subsequently calling the gotfocus event ? – Madi D. Jan 05 '10 at 10:54
  • Also, the GotFocus will fire every time you change to that form. Example, minimize and restore will cause it to fire again. – monkey_p Jan 05 '10 at 10:54
  • Actually i just edited because i noticed it will keep firing, so i added a comment to remind him to change Focus at the end, however if he doesn't want the event to re-fire for minimizing or restore, they can add a variable to handle first Focus and set it true after the 1st time the event gets called. – Madi D. Jan 05 '10 at 11:01