Windows form is loaded

Winforms: How to display a “loading” form?

I have a grid and when a row is double clicked a form is loaded. However a lot of data must be loaded, so I’d like to display a simple form with the text ‘loading, please wait..’. And when all loading is finished, the form must disappear.

This is what I have right now, but it doesn’t work:

Code that invokes the form with lots of data:

Constructor of FormWithLotData:

Hope you can help me out.

EDIT: I’d like to show an animated gif on the loading form.

SOLUTION: I’ve created a background worker. The DoWork event handles all the loading and by using the invoke() method I add nodes to the treeview. Now, the GUI doesn’t hang and the user don’t have the idea that the application is hanging.

5 Answers 5

You need to reverse your code.

The constructor of FormWithLotData is running in the UI thread. This is the thread that must show your FormIsLoading form. So instead of trying to display this form using the new Thread, do your data loading with it.

The DoEvents way others have suggested is the easiest to implement and (possibly? never done it myself) may work well.

The better pattern to use is to do your data loading on a worker thread. Before you show your FormWithLotData, Begin loading data on a background thread and show your Loading dialog. The method that loads the data should have a callback method into the Loading dialog to signal when it should Close(). Once it closes you can then construct a new FWLD, pass it the already loaded data, and Show it.

Trying to load your data after the form has already been invoked mixes your UI with your data operations, forcing your form to not only be in charge of the UI but also be in charge of data retrieval. Bad for KISS and Single Responsibility, imho.

After your update, it seems like DoEvents is going to be the only real answer to your question, but with some caveats.

You will not be able to show another form MODALLY while you construct your tree. You will still have to do your heavy work within your form’s constructor. You will still have to hide your main form and Show() (not ShowDialog) your loading form. You will also have to call DoEvents at every single possible moment while constructing your tree. Its not exactly an elegant solution, but it will probably be your best bet at this point.

How do I execute code AFTER a form has loaded?

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?

8 Answers 8

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

I sometimes use (in Load)

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

Читайте также:  Восстановить загрузки после обновления windows

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:

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!).

First time it WILL NOT start «AfterLoading»,
It will just register it to start NEXT Load.

I had the same problem, and solved it as follows:

Actually I want to show Message and close it automatically after 2 second. For that I had to generate (dynamically) simple form and one label showing message, stop message for 1500 ms so user read it. And Close dynamically created form. Shown event occur After load event. So code is

You could also try putting your code in the Activated event of the form, if you want it to occur, just when the form is activated. You would need to put in a boolean «has executed» check though if it is only supposed to run on the first activation.

This an old question and depends more upon when you need to start your routines. Since no one wants a null reference exception it is always best to check for null first then use as needed; that alone may save you a lot of grief.

The most common reason for this type of question is when a container or custom control type attempts to access properties initialized outside of a custom class where those properties have not yet been initialized thus potentially causing null values to populate and can even cause a null reference exceptions on object types. It means your class is running before it is fully initialized — before you have finished setting your properties etc. Another possible reason for this type of question is when to perform custom graphics.

To best answer the question about when to start executing code following the form load event is to monitor the WM_Paint message or hook directly in to the paint event itself. Why? The paint event only fires when all modules have fully loaded with respect to your form load event. Note: This.visible == true is not always true when it is set true so it is not used at all for this purpose except to hide a form.

The following is a complete example of how to start executing you code following the form load event. It is recommended that you do not unnecessarily tie up the paint message loop so we’ll create an event that will start executing your code outside that loop.

Читайте также:  Mac os bios settings

How to display a “loading” overlay on windows forms while the form is loading its controls (or updating them)?

I’m looking for an effective way to notify the user that a given form is currently loading (or updating) it’s UI and it will take few seconds.

This may occurs at initial load or at update. Since it’s very intensive and modifying ui controls, this has to be done on the ui thread, and therefore blocking the user.

Changing the cursor is not enought, I want to get a similar effect than on ajax pages, with the whole area that is overlayed by a semi transparent panel with an animated gear on the center.

Have you done something like that already? Or do you know interesting websites I should consult?

6 Answers 6

Take a look at this post with a great answer that mimics the Ajax style on WinForms

Here is a custom Form that’ll do what you want. alter to your taste:

You can create a transparent panel by subclassing S.W.F.Panel and overriding the CreateParams property:

Override the OnPaint to add a semi transparent overlay:

Set this panel on Dock.Fill on your form over the other controls. Hide it when loading ends.

Note that Winforms does not allow child controls to actually be transparent. As others have posted a separate transparent window is possible — but messy to manage.

Cheap way

  • drag all controls into one panel and make it the size of the window (easy change)
  • When operating: Hide that panel. Use the panels .DrawToBitmap method to set form background image.
  • show progress bar, do work with ‘doevents,’ hide it.
  • clear background image, re-show panel.

A Better way:

Progress Class — Consumer

I will give you a Usercontrol I wrote and have used in many different programs that does exactly what you want. Here is a trivial consumer example, you can paste into a form’s code (yes, it just makes a bunch of new buttons for no reason):

Progress Class — Definition

And here is the class. The ‘designer’ code is pasted inline, you can leave it there. The class disables controls when running so all you can do is cancel. It runs on the GUI thread. You can disable the cancel option. In the consumer is an example of dealing with newly added controls so they don’t show up enabled, but get enabled when the progress is over.

You can disable all controls on the form by setting the Enabled property to False and then changing it back to True after the process is done.

In addition you can have a hidden label that says «Loading» that you display before disabling the form and hide when re-enabling it.

Finally, I would suggest that you split the process in two parts. One part that does the work without modifying controls that you can run on a worker thread and the part that changes the gui that does it work on the gui thread after the worker thread is done. This way you won’t block the entire application, making changes to the Gui easier to do.

Load vs. Shown events in Windows Forms

Hopefully I’m just missing something obvious, but I’m trying to get my head around the differences between the Load and the Shown events in Windows Forms.

Traditionally, I’ve only used Load (or actually OnLoad, since I think it’s cleaner to override a method than to rely on the designer to hook up an event on yourself), since that is available in all versions of .NET. With .NET 2.0 the Shown event was introduced.

Читайте также:  Логин под другим пользователем linux

Now, if you look at the descriptions for these in the MSDN documentation («Load: Occurs before a form is displayed for the first time.», «Shown: Occurs whenever the form is first displayed.») it sounds like the Load event should occur, then the form should become visible, then the Shown event should occur; the combination of the two thereby letting you carry out some tasks both before and after the form is visible. Makes sense, right?

However, experimentation has shown that the Shown event invariably occurs before the Load event, whenever I try it (and both occur before the form becomes visible). And yet, when I google around whenever I discover a page that talks about the order these events are fired in, they always list the Load event being fired first.

Am I just going crazy, or have I missed something? (And if they do occur at about the same time, then why was the Shown event added in the first place?)

(My current solution for doing something both before and after showing the form is to use OnLoad for the «before showing» stuff and start a short-duration one-shot timer for the «after showing» stuff. Which works OK and reliably, but it’s a bit ugly and I was hoping there was a cleaner solution. But it looks like the Shown event isn’t it.)

C# unload and load form / hide and close

I am coding a simple sidescroller in C# using Windows Form Applications. I want it so when the player touches an exit point, this immediately loads a new level.

To implement this, I use the following code:

This works. However, it loads numerous instances of form2 — I only want it to load once. I don’t know how to write this (sorry, I’m a newbie — it took me a while just to write this code!).

Also, loading a level via a new form is inefficient. Is there a way to unload the open form to load the next one in the same window/instance, rather than creating another separate window?

Sorry if this is unclear. I’ve done my best research + I’m new. Please don’t mention XNA! Thanks.

3 Answers 3

You need a small modification to your project’s Program.cs file to change the way your app decides to terminate. You simple exit when there no more windows left. Make it look like this:

Now it is simple:

You can use Application.OpenForms[] collection to retrieve the Opened form instance and then Show it.

The actual problem is not in your form being loaded multiple times, but in your game logic not being suspended when the end of the level is reached. It means that your game keeps playing an old level when a new level is already loaded.

If Form1 is the main form then your whole application will shutdown. You need bootstraper which will be the entry point of your application, not the Form1. If you do that your Form1 will be a child in the same sense as will be Form2. You can open and close them without shutting down the application. If you don’t know how to do that, just create another empty form, let’s call it Main and make it the starting form of your application. Then hide it and open Form1 from Main form as Modal. Then when you complete level in Form1, close Form1, the code flow will return to Main form and you’ll spawn Form2 from Main form as Modal. You’ll have fully predictable logic, where all forms are opened from a single controlled place.

Оцените статью