Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know when all controls have loaded and displayed?

Tags:

c#

.net

winforms

What is the real order of events in a Windows Forms application?

What I mean is, when I put code in the Form_Shown event, I expect that code only to run after the form has been Shown:

verb (used with object), showed, shown or showed, showing. 1. to cause or allow to be seen... - http://dictionary.reference.com/browse/shown

But the Form_Shown event is a little misleading. If I do some heavy stuff inside that event, it seems as though the code gets executed before the Form has finished been shown. Let's say that I have a MainMenu, a small Toolbar and a TextBox on a form.

I want to do some heavy stuff (nevermind threads and workers for now...), so the last event I can use I would think would be Form_Shown. So I put my heavy code in there, but when the Form begins to display, I end up waiting ~ 5 - 6 seconds for the Toolbar and stuff to display (which ends up happening after my heavy code does its thing.

Which leads me to believe that I'm subscribing to the wrong event. I don't want the Form_Shown event at all. What I really need is:

Form_WhenALLTheThingsHaveShownEventHandler event.

So, how can I know _when all the things (controls) have been fully loaded and displayed?

like image 369
NDEIGU Avatar asked May 13 '15 04:05

NDEIGU


People also ask

What event happens just before a form is displayed on the screen?

Load: This event occurs before a form is displayed for the first time. VisibleChanged: This event occurs when the Visible property value changes.

Which event will occur whenever the user control load?

The Load event occurs when the handle for the UserControl is created. In some circumstances, this can cause the Load event to occur more than one time. For example, the Load event occurs when the UserControl is loaded, and again if the handle is recreated.

Which event is executed first for form control?

Activated: This event occurs when the form is activated in code or by the user. Shown: This event occurs whenever the form is first displayed. Paint: This event occurs when the control is redrawn. Deactivate: This event occurs when the form loses focus and is not the active form.

Which function is called for loading of a window form?

Load Event (System. Windows.


1 Answers

The Shown event is in fact the last event related to initialization that is raised. However, note that the actual rendering (drawing on-screen) of UI objects in Windows (and on other platforms) is deferred. The creation of a UI object merely allocates all the necessary resources and "invalidates" the visual area of the object. The platform then later schedules the rendering event (in unmanaged Windows, this is WM_PAINT, in the Winforms API this would be the Paint event for a Control instance).

The rendering event cannot be dispatched until the UI object's thread is available, and if you have long-running code in the Shown event, that will keep the UI object's thread unavailable for the duration of your code. I.e. nothing gets drawn until your code completes.

There are other events that you could use to more reliably detect when things have "settled down". For example, the Application.Idle event tells you when the main application thread is about to enter the idle state. Alternatively, you could just subscribe to the form's Paint event. In either case, you would want to use BeginInvoke() to dispatch your long-running code, so that you don't block the handling of those events.


Now, all that said: you really should not be performing any long-running work in the UI thread, period. Using either of the above events doesn't solve the underlying problem; it simply delays the problem until after the initial rendering of your UI. The UI will still remain blocked while your long-running work is executing, and frankly the user may actually find it preferable for there to be no UI at all, than for there to be something that looks like they can interact with but which they can't (i.e. is unresponsive to their input).

In the latest version of .NET, there are some very nice mechanisms available for shifting long-running work to background threads, so that the UI can remain responsive. See Task and the async and await keywords in C#. You could instead use the older BackgroundWorker object to accomplish the same, if you prefer.

like image 74
Peter Duniho Avatar answered Oct 17 '22 04:10

Peter Duniho