Search code examples
c#wpfuser-interfacesplash-screen

How can I make a good splash screen that does two actions at once?


I'm currently trying to make a splash screen, however, I can't seem to be able to make a few tasks setup things at once.

I've tried using the BackgroundWorker class, as well as the Thread class, and none seem to work.

In the App.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
{
    var splashScreen = new Windows.Splash();
    splashScreen.Show();

    base.OnStartup(e);

    splashScreen.Close();
}

In the splashScreen.xaml.cs:

public Splash()
{
    InitializeComponent();
    DataContext = this;

    changeLoadingTxtTimer = new System.Timers.Timer(2000);
    changeLoadingTxtTimer.Elapsed += Timer_Elapsed;

    backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += D_DoWork;
    backgroundWorker.RunWorkerAsync();

    changeLoadingTxtTimer.Start();
}

private void D_DoWork(object sender, DoWorkEventArgs e) { UpdateDatabase(); }

private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    LoadingTxtValue = LoadingTxts[rd.Next(0, LoadingTxts.Length - 1)];

    if (!backgroundWorker.IsBusy)
        changeLoadingTxtTimer.Stop();
    }
}

I expect that as the BackgroundWorker works, the loading text will change every 2 seconds, but what actually happens is that the BackgroundWorker finishes its job, and the splash screen closes.


Solution

  • App.xaml

    Remove the StartupUri entry

    <Application
          x:Class="WpfSplashApp.App"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="clr-namespace:WpfSplashApp">
        <Application.Resources />
    </Application>
    

    App.xaml.cs

    public partial class App : Application
    {
        public App()
        {
            Startup += App_Startup;
        }
    
        private async void App_Startup( object sender, StartupEventArgs e )
        {
            var splash = new SplashWindow();
            splash.Show();
    
            await InitializeAsync();
    
            var main = new MainWindow();
            main.Show();
            MainWindow = main;
    
            splash.Close();            
        }
    
        private Task InitializeAsync()
        {
            // Do some ASYNC initialization 
            return Task.Delay( 5000 );
        }
    }