6

I am trying to make the splash screen appears first and after the splash, the MainForm appears. But the progress bar which I have in splash screen don't get to the end of the bar. And the program continues running and not works.

How can I show the splash screen during loading the main form?

My code It's something like that :

public partial class SplashForm : Form
{
    public SplashForm()
    { 
        InitializeComponent();
    }
    private void SplashForm_Load(object sender, EventArgs e)
    {
        timer1.Enabled = true;
        timer1.Start();
        timer1.Interval = 1000;
        progressBar1.Maximum = 10;
        timer1.Tick += new EventHandler(timer1_Tick);
    }
    public void timer1_Tick(object sender, EventArgs e)
    {
        if (progressBar1.Value != 10)
        {
            progressBar1.Value++;
        }
        else
        {
            timer1.Stop();
            Application.Exit();
        }
    }     
}

Here are the first part of the code of the MainForm:

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        Application.Run(new SplashForm());
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Leandro Mont
  • 103
  • 2
  • 3
  • 11
  • Can you show the code that creates this form? Where is the pbcarrega initialized? – Paul Sasik Sep 05 '15 at 23:51
  • pbcarrega is the name of the ProgressBar – Leandro Mont Sep 06 '15 at 00:00
  • This code is the code of the Form Splash Screen,but you want to know about the Form Main ? – Leandro Mont Sep 06 '15 at 00:05
  • @Novatec - You need to provide us with enough code for us to recreate your problem. Just picking a few lines of code that you think is relevant is not enough. Please post the [minimal, complete, and verifiable](https://stackoverflow.com/help/mcve) code to replicate your problem. – Enigmativity Sep 06 '15 at 02:30
  • I posted now the part of the Form Main,I was looking and I think I did something wrong in that part of Application.Run() – Leandro Mont Sep 06 '15 at 02:59
  • Now after I changed the code,the ProgressBar get to value 100,but I don't know how to show the Form Main after the Splash Screen. – Leandro Mont Sep 06 '15 at 03:03

2 Answers2

25

There are different ways of creating splash screens:

  • You can rely on the splash screen feature of WindowsFormsApplicationBase

  • You can show implement the feature yourself by showing a form on a different UI thread and hiding it after the main from loaded successfully.

In this post I'll show an example of both solutions.

Note: Those who are looking for showing a loading window or a loading gif animation during loading of data, can take a look at this post: Show Loading animation during loading data in other thread

Option 1 - Use WindowsFormsApplicationBase Splash Screen feature

  1. Add a reference of Microsoft.VisualBasic.dll to your project.
  2. Create a MyApplication class by deriving from WindowsFormsApplicationBase
  3. override OnCreateMainForm and assign the from that you want to be the startup form to MainForm property.
  4. Override OnCreateSplashScreen and assign the form that you want to show as splash screen to SplashScreen property.

  5. In your Main method, create an instance of MyApplication and call its Run method.

Example

using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(true);
        var app = new MyApplication();
        app.Run(Environment.GetCommandLineArgs());
    }
}
public class MyApplication : WindowsFormsApplicationBase
{
    protected override void OnCreateMainForm()
    {
        MainForm = new YourMainForm();
    }
    protected override void OnCreateSplashScreen()
    {
        SplashScreen = new YourSplashForm();
    }
}

Option 2 - Implement the feature using a different UI thread

You can implement the feature yourself by showing the splash screen in a different UI thread. To do so, you can subscribe to Load event of the main form in Program class, and show and close your splash screen there.

Example

using System;
using System.Threading;
using System.Windows.Forms;

static class Program
{
    static Form SplashScreen;
    static Form MainForm;
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        //Show Splash Form
        SplashScreen = new Form();
        var splashThread = new Thread(new ThreadStart(
            () => Application.Run(SplashScreen)));
        splashThread.SetApartmentState(ApartmentState.STA);
        splashThread.Start();

        //Create and Show Main Form
        MainForm = new Form8();
        MainForm.Load += MainForm_LoadCompleted;
        Application.Run(MainForm);
    }
    private static void MainForm_LoadCompleted(object sender, EventArgs e)
    {
        if (SplashScreen != null && !SplashScreen.Disposing && !SplashScreen.IsDisposed)
            SplashScreen.Invoke(new Action(() => SplashScreen.Close()));
        MainForm.TopMost = true;
        MainForm.Activate();
        MainForm.TopMost = false;
    }
}

Note: To show a smooth edge custom shaped splash screen take a look at this post: Windows Forms Transparent Background Image.

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Can you put this code with my name of form and variable ? – Leandro Mont Sep 06 '15 at 18:25
  • 1
    I changed the names to be more friendly to you. Now to use this code with the name of your forms, its enough to find and replace all SplashForm with the name that you want for your splash form (FormSplash) and find and replace all MainForm with the name that you want for your main form (Form1). – Reza Aghaei Sep 06 '15 at 19:28
  • 1
    I can use this same code changing some parts for use in ProgressBar ? Because the Thread.Sleep I will for now not use. – Leandro Mont Sep 07 '15 at 18:56
  • 1
    @Novatec You can change any part of code and bend it to your will, but I don't recommend you to use a progress bar in your splash screen, instead,simply show a loading image (an animated .gif) in splash screen. I think this is a good implementation of splash screen that will be helpful to other users too:) – Reza Aghaei Sep 07 '15 at 18:58
  • Thanks man ,your answer was truly helpful,so I vote it up.But I have one question,why It's better use Thread.Sleep than ProgressBar ? – Leandro Mont Sep 07 '15 at 20:36
  • @Novatec Thank you and you are welcome, `Thread.Sleep` is never better than progress bar. In above code `Thread.Sleep` is just for test to make delay to simulate a heavy form load. What is better and easier than progress bar is using a loading animated gif. – Reza Aghaei Sep 08 '15 at 02:05
  • @LeandroMont what is minScreen in Application.Run(minScreen); – Rawat Apr 07 '18 at 07:37
  • @Rawat It's a typo. It should be `myMainForm`. Feel free to edit the answers when you find such obvious typo :) – Reza Aghaei Apr 07 '18 at 07:59
  • 1
    I tried this sample and its working but when my splashscreen closes my form goes in background. any suggestion to overcome from that – Rawat Apr 07 '18 at 10:11
  • 1
    @Rawat I couldn't reproduce the problem, but as a suggestion, in `MainForm_LoadCompleted` event handler, instead of `myMainForm.Activate();` you can use `myMainForm.TopMost = true; myMainForm.Activate(); myMainForm.TopMost = false;` – Reza Aghaei Apr 07 '18 at 11:09
  • I edited the code a bit (activated splash screen after showing main form). – Reza Aghaei Apr 07 '18 at 11:15
  • This is an awesome solution, Can I set a timer on how long to show the splash screen? Thanks. – Si8 Dec 16 '20 at 13:46
  • 1
    @Si8 Yes you can manage that, but the whole point of splash screen is just showing it while loading. If you want a timer based solution, you don't need any of above solutions. – Reza Aghaei Dec 16 '20 at 17:59
0

I have had a splash in my Winforms application for years. The splash stays on for 5 seconds and is non-modal, but topmost. Initialisations keep running without issues.

In main program, I changed nothing

    [STAThread]
    static void Main()
    {
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new FrmMain());
    }

    //---------------------------------------------------------------------

This is my splash, it has a timer that closes it after 5 seconds

    public partial class FrmSplash : Form
    {
      private Timer _timer;
      private int _cTick = 5;

      public FrmSplash()
      {
        InitializeComponent();
        _timer = new Timer() { Interval = 1000, Enabled = true };
        _timer.Tick += CTick;
      }

      private void CTick(object sender, EventArgs e)
      {
        if (--_cTick<0)
        {
            _timer.Enabled = false;
            Close();

        }
      }
   }

In the main form constructor, I call the splash followed by Application.DoEvents() so it will be shown on the screen, meanwhile my initialisations can proceed,

   //---------------------------------------------------------------------

   public FrmMain()
   {
      InitializeComponent();
      var  FrmSplash = new FrmSplash();
      FrmSplash.Show();
      Application.DoEvents();
   }
Goodies
  • 1,951
  • 21
  • 26