[c#] How do I show a "Loading . . . please wait" message in Winforms for a long loading form?

I have a form that is very slow because there are many controls placed on the form.

As a result the form takes a long time to loaded.

How do I load the form first, then display it and while loading delay show another form which that have message like "Loading... please wait.?"

This question is related to c# .net winforms .net-core

The answer is


I know it is wery late, but I fonded this project and I would like to share with you, it is very usefull and sample Simple Display Dialog of Waiting in WinForms


You want to look into 'Splash' Screens.

Display another 'Splash' form and wait until the processing is done.

Here is an example on how to do it.


You can take a look at my splash screen implementation: C# winforms startup (Splash) form not hiding


You should create a background thread to to create and populate the form. This will allow your foreground thread to show the loading message.


I put some animated gif in a form called FormWait and then I called it as:

// show the form
new Thread(() => new FormWait().ShowDialog()).Start();

// do the heavy stuff here

// get the form reference back and close it
FormWait f = new FormWait();
f = (FormWait)Application.OpenForms["FormWait"];
f.Close();

I looked at most the solutions posted, but came across a different one that I prefer. It's simple, doesn't use threads, and works for what I want it to.

http://weblogs.asp.net/kennykerr/archive/2004/11/26/where-is-form-s-loaded-event.aspx

I added to the solution in the article and moved the code into a base class that all my forms inherit from. Now I just call one function: ShowWaitForm() during the frm_load() event of any form that needs a wait dialogue box while the form is loading. Here's the code:

public class MyFormBase : System.Windows.Forms.Form
{
    private MyWaitForm _waitForm;

    protected void ShowWaitForm(string message)
    {
        // don't display more than one wait form at a time
        if (_waitForm != null && !_waitForm.IsDisposed) 
        {
            return;
        }

        _waitForm = new MyWaitForm();
        _waitForm.SetMessage(message); // "Loading data. Please wait..."
        _waitForm.TopMost = true;
        _waitForm.StartPosition = FormStartPosition.CenterScreen;
        _waitForm.Show();
        _waitForm.Refresh();

        // force the wait window to display for at least 700ms so it doesn't just flash on the screen
        System.Threading.Thread.Sleep(700);         
        Application.Idle += OnLoaded;
    }

    private void OnLoaded(object sender, EventArgs e)
    {
        Application.Idle -= OnLoaded;
        _waitForm.Close();
    }
}

MyWaitForm is the name of a form you create to look like a wait dialogue. I added a SetMessage() function to customize the text on the wait form.


Another way of making "Loading screen" only display at certain time is, put it before the event and dismiss it after event finished doing it's job.

For example: you want to display a loading form for an event of saving result as MS Excel file and dismiss it after finished processing, do as follows:

LoadingWindow loadingWindow = new LoadingWindow();

try
{
    loadingWindow.Show();                
    this.exportToExcelfile();
    loadingWindow.Close();
}
catch (Exception ex)
{
    MessageBox.Show("Exception EXPORT: " + ex.Message);
}

Or you can put loadingWindow.Close() inside finally block.


or if you don't want anything fancy like animation etc. you can create a label and dock it to form then change it's z-index from document outline window to 0 and give it a background color so other controls wont be visible than run Application.DoEvents() once in form load event and do all your coding in form shown event and at the and of shown event set your label visible property to false then run Application.DoEvents() again.


Well i do it some thing like this.

        NormalWaitDialog/*your wait form*/ _frmWaitDialog = null;


        //Btn Load Click Event
        _frmWaitDialog = new NormalWaitDialog();
        _frmWaitDialog.Shown += async (s, ee) =>
        {
            await Task.Run(() =>
           {
               // DO YOUR STUFF HERE 

               //Made long running loop to imitate lengthy process
               int x = 0;
               for (int i = 0; i < int.MaxValue; i++)
               {
                   x += i;
               }

           }).ConfigureAwait(true);
            _frmWaitDialog.Close();
        };
        _frmWaitDialog.ShowDialog(this);

A simple solution:

using (Form2 f2 = new Form2())
{
    f2.Show();
    f2.Update();

    System.Threading.Thread.Sleep(2500);
} // f2 is closed and disposed here

And then substitute your Loading for the Sleep.
This blocks the UI thread, on purpose.


The best approach when you also have an animated image is this one:

1- You have to create a "WaitForm" that receives the method that it will executed in background. Like this one

public partial class WaitForm : Form
{
    private readonly MethodInvoker method;

    public WaitForm(MethodInvoker action)
    {
        InitializeComponent();
        method = action;
    }

    private void WaitForm_Load(object sender, EventArgs e)
    {
        new Thread(() =>
        {
            method.Invoke();
            InvokeAction(this, Dispose);
        }).Start();
    }

    public static void InvokeAction(Control control, MethodInvoker action)
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(action);
        }
        else
        {
            action();
        }
    }
}

2 - You can use the Waitform like this

private void btnShowWait_Click(object sender, EventArgs e)
{
    new WaitForm(() => /*Simulate long task*/ Thread.Sleep(2000)).ShowDialog();
}

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to winforms

How to set combobox default value? Get the cell value of a GridView row Getting the first and last day of a month, using a given DateTime object Check if a record exists in the database Delete a row in DataGridView Control in VB.NET How to make picturebox transparent? Set default format of datetimepicker as dd-MM-yyyy Changing datagridview cell color based on condition C# Inserting Data from a form into an access Database How to use ConfigurationManager

Examples related to .net-core

dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Assets file project.assets.json not found. Run a NuGet package restore Is ConfigurationManager.AppSettings available in .NET Core 2.0? How to update record using Entity Framework Core? Using app.config in .Net Core EF Core add-migration Build Failed Build .NET Core console application to output an EXE What is the difference between .NET Core and .NET Standard Class Library project types? Where is NuGet.Config file located in Visual Studio project?