views:

3400

answers:

4

I have a winforms application in which I am using 2 Forms to display all the necessary controls. The first Form is a splash screen in which it tells the user that it it loading etc. So I am using the following code:

Application.Run( new SplashForm() );

Once the application has completed loading I want the SplashForm to hide or me sent to the back and the main from to be show. I am currently using the following:

private void showMainForm()
{
    this.Hide();
    this.SendToBack();

    // Show the GUI
    mainForm.Show();
    mainForm.BringToFront();
}

What I am seeing is that the MainForm is shown, but the SplashForm is still visible 'on top'. What I am currently doing is clicking on the MainForm to manually bring it to the front. Any ideas on why this is happening?

+4  A: 

Probably you just want to close the splash form, and not send it to back.

I run the splash form on a separate thread (this is class SplashForm):

class SplashForm
{
    static public void ShowSplashScreen()
    {
        // Make sure it is only launched once.

        if (splashForm != null)
            return;
        Thread thread = new Thread(new ThreadStart(SplashForm.ShowForm));
        thread.IsBackground = true;
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();           
    }

    static private void ShowForm()
    {
        splashForm = new SplashForm();
        Application.Run(splashForm);
    }

    static public void CloseForm()
    {
        splashForm.Invoke(new CloseDelegate(SplashForm.CloseFormInternal));
    }

    static private void CloseFormInternal()
    {
        splashForm.Close();
    }
...
}

and the main program function looks like this:

[STAThread]
static void Main(string[] args)
{
    SplashForm.ShowSplashScreen();
    MainForm mainForm = new MainForm(); //this takes ages
    SplashForm.CloseForm();
    Application.Run(mainForm);
}
Grzenio
This method doesn't work if the SplashForm is a WPF Window
MrEdmundo
I use it only for WinForms, sorry.
Grzenio
I defined a variable like "frmSplash splashForm" in your class but i get some of errors like "An object reference is required for the non-static field, method, or property" for defined variable. how can i use from your class?
Sadegh
+1  A: 

If I have understood correctly, you should just use Application.Run on your main form. So either show your splash first just by using something like:

using(MySplash form = new MySplash())
   form.ShowDialog();

And then close it manually in MySplash whenever you want to.

Or show it in your main forms Load event handler and then wait for it to close or whatever until you let the Load method complete. (Possibly setting Visible to false before you show it and back to true afterwards.

Svish
A: 

I believe that it might be a design flaw in my current design!

I think the best Way to achieve what I need is to have everything controled from the MainForm. So I can use:

Application.Run(new MainForm());

This will then be responsable for showing/updating/hiding the SplashScreen. This way I can have the necessary complex intactions with the rest of the system managed by the MainForm.

TK
A: 

This is crucial to prevent your splash screen from stealing your focus and pushing your main form to the background after it closes:

protected override bool ShowWithoutActivation {
    get { return true; }
}

Add this to you splash form class.

Luke