The Mask
The Mask

Reputation: 17427

How do I display something like "loading.." while I do some checks on form load?

I do some checks on form load, but it is locking the form for a period (some thousandths of seconds). For this reason, I want to display a message such as "loading application..", but I have no idea how I do this. I hope this clear! Any help is very appreciated. Thanks in advance.

Upvotes: 5

Views: 9843

Answers (5)

Er Ketan Vavadiya
Er Ketan Vavadiya

Reputation: 281

You need to create one form that is frmloading here.. you need to create object of that form and called using threading concept..and in FrmLoading put one Picturebox and set .gif image in it.

FrmLoading f2 = new FrmLoading();
using (new PleaseWait(this.Location, () =>MethodWithParameter())) {      f2.Show(this); }
f2.Close();

As shown above code you need to create PleaseWait class.

PleaseWait.cs

public class PleaseWait : IDisposable
{
private FrmLoading mSplash;
private Point mLocation;

public PleaseWait(Point location, System.Action methodWithParameters)
{
    mLocation = location;
    Thread t = new Thread(new ThreadStart(workerThread));
    t.IsBackground = true;
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
    methodWithParameters();
}
public void Dispose()
{
    mSplash.Invoke(new MethodInvoker(stopThread));
}
private void stopThread()
{
    mSplash.Close();
}
private void workerThread()
{
    mSplash = new FrmLoading();   // Substitute this with your own
    mSplash.StartPosition = FormStartPosition.CenterScreen;
    //mSplash.Location = mLocation;
    mSplash.TopMost = true;
    Application.Run(mSplash);
}
}

Upvotes: 0

Dirk Strauss
Dirk Strauss

Reputation: 641

This can be accomplished easily by displaying a separate form executed on another thread. In this form (call it frmSplash) you can put an animated gif or static text. The code you will need is as follows in your main form:

Declare some variables after the class.

public partial class frmMain : Form
{
   public Thread th1;
   static frmSplash splash;
   const int kSplashUpdateInterval_ms = 1;

// Rest of code omitted

Then add the following method to your main form. This starts the splash screen:

static public void StartSplash()
{
    // Instance a splash form given the image names
    splash = new frmSplash(kSplashUpdateInterval_ms);

    // Run the form
    Application.Run(splash);
} 

Next, you need a method to close the splash screen:

private void CloseSplash()
{
    if (splash == null)
        return;

    // Shut down the splash screen
    splash.Invoke(new EventHandler(splash.KillMe));
    splash.Dispose();
    splash = null;
} 

Then, in your main Form Load, do this:

private void frmMain_Load(object sender, EventArgs e)
{
    try
    {
        Thread splashThread = new Thread(new ThreadStart(StartSplash));
        splashThread.Start();

        // Set the main form invisible so that only the splash form shows
        this.Visible = false;

        // Perform all long running work here. Loading of grids, checks etc.
        BindSalesPerson();
        BindCustomer();
        BindBrand();

        // Set the main form visible again
        this.Visible = true;
    }
    catch (Exception ex)
    {
        // Do some exception handling here
    }
    finally
    {
        // After all is done, close your splash. Put it here, so that if your code throws an exception, the finally will close the splash form
        CloseSplash();
    }

} 

Then, if the main form is closed, make sure your splash screen is closed also:

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    // Make sure the splash screen is closed
    CloseSplash();
    base.OnClosing(e);
} 

The code for the Splash form (In frmSplash.cs) is as follows:

public partial class frmSplash : Form
{

    System.Threading.Timer splashTimer = null;
    int curAnimCell = 0;
    int numUpdates = 0;
    int timerInterval_ms = 0;

    public frmSplash(int timerInterval)
    {
        timerInterval_ms = timerInterval;

        InitializeComponent();
    } 


    private void frmSplash_Load(object sender, EventArgs e)
    {
        this.Text = "";
        this.MaximizeBox = false;
        this.MinimizeBox = false;
        this.ControlBox = false;
        this.FormBorderStyle = FormBorderStyle.None;
        this.Menu = null;
    } 

    public int GetUpMilliseconds()
    {
        return numUpdates * timerInterval_ms;
    }

    public void KillMe(object o, EventArgs e)
    {
        //splashTimer.Dispose();

        this.Close();
    }        
}

I hope this helps you. It might not be the best code ever written, but it worked for me.

Upvotes: 2

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57650

Have a look at BackgroundWorker component. You dont need any threading knowledge at all.

Upvotes: 2

Chris Shain
Chris Shain

Reputation: 51339

Ideally what you want to do is to perform your checks on a background thread, so that the UI thread isn't blocked. Have a look at the BackgroundWorker class.

You should hook your checks to the DoWork event of the background worker, and call the BackgroundWorker's RunWorkerAsync() method from the Form_Load event to kick off the background work.

Something like this (note, this is untested):

BackgroundWorker bw = new BackgroundWorker();
public void Form_Load(Object sender, EventArgs e) {
    // Show the loading label before we start working...
    loadingLabel.Show();
    bw.DoWork += (s, e) => {
       // Do your checks here
    }
    bw.RunWorkerCompleted += (s, e) => { 
       // Hide the loading label when we are done...
       this.Invoke(new Action(() => { loadingLabel.Visible = false; })); 
    };
    bw.RunWorkerAsync();
}

Upvotes: 10

Axis
Axis

Reputation: 846

You can create another thread to display the loading message.

First you need a bool.

bool loading = true;

Create a thread like:

Thread myThread = new Thread(new ThreadStart(Loading));
myThread .Start();

Then have a method:

private void Loading()
{
    while(loading)
    {
        //Display loading message here.
    }
}

When you are done loading whatever just set loading to false and the tread will terminate.

Upvotes: 2

Related Questions