简体   繁体   中英

Is there a similar way to Form.Shown later in a form's lifetime?

Understanding that I can use the Forms.Shown event to be notified when a form fully is shown for the very first time, I found no way yet to get something similar later in the form's lifetime.

Ie consider adding/removing controls or resizing the form.

I thought about registering for the Application.Idle event and somehow connect this to my form but I'm unsure whether this is the right way to go.

In addition I thought about subclassing the LayoutEngine class to gain access to some events/overrides. Again this doesn't look the right way to go for me.

So my question is:

When programmatically adding/removing/resizing a control when a form is already visible, how can I detect when the form is fully finished layouting and drawing again?

Ie consider adding/removing controls or resizing the form

No, you never want to do this when the user can see the window. There are two basic places where you want to write code like this before the user can see you monkeying with the window, actually seeing it changing size, moving around and generally flickering madly because of multiple Paint events.

First and foremost is your class constructor. That's where you initialize the object in .NET, adding or removing controls belongs there.

Secondary is the Load event. An event that's generally very poorly understood and gets used way to often in Winforms. Induced by it being the default event for the Form class, an historical accident that goes back to early versions of Visual Basic where it was the event to use to initialize the form. That is no longer appropriate, .NET class objects should be initialized in their constructor.

Load, or rather OnLoad(), is appropriate when your code needs to know the Location or Size of the window. Everything that needs to happen to the native window is done by then. It has a valid Handle property, Windows picked a Location, it got rescaled if necessary to accommodate the machine's DPI setting, its Size property is now valid, reflecting scaling and any user preferences, layout was performed so every control is in its expected place. The only thing that didn't happen yet is that the Paint event wasn't fired yet. So the window is not yet visible to the user. That happens very soon after Load completes.

So sizing or moving the window is typically appropriate in OnLoad, given that you now know the real size and location. Do beware DPI rescaling, never hard-code a size.

If you need code run some fixed time after the window is displayed then a Timer is appropriate.

I'm taking a guess here, but the form's OnPaint event might do the trick. You can just override the base OnPaint handler, call the parent function, and put any logic you have after that.

You could use separate events call for each of the events that call a common function

IE ResizeEnd for resizing, ControlAdded and ControlRemoved for the controls.

private void Form1_ResizeEnd(object sender, EventArgs e)
{
    DoWork()
}

private void Form1_ControlAdded(object sender, ControlEventArgs e)
{
   DoWork()
}

private void Form1_ControlRemoved(object sender, ControlEventArgs e)
{
   DoWork() 
}

private void DoWork()
{
  //What needs to be done for each of them
}

Im not sure about the timing of these calls though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM