lentinant
lentinant

Reputation: 832

When does the WPF SplashScreen close?

I'm working on a custom splash-screen (since the standard one doesn't fit my needs). But there is one option I'd like to have from it - auto-close. But to implement it, I need to understand how the common SplashScreen selects the moment to close.

So, is there any sort of event to message the splash screen, to tell it that it should be closed? What event does the common splash-screen use, at least?

Upvotes: 3

Views: 3302

Answers (2)

Hans Passant
Hans Passant

Reputation: 942070

The WPF SplashScreen class uses a very simple trick, it calls Dispatcher.BeginInvoke().

The expectation is that the UI thread is grinding away getting the program initialized and is therefore not dispatching anything. It is "hung". Not forever of course, as soon as it is done, it re-enters the dispatcher loop and now the BeginInvoked method gets a chance, the ShowCallback() method runs. Poorly named, should be "CloseCallback" :) A 0.3 second fade covers up any additional delay in getting the main window to render.

In general, calling Dispatcher.BeginInvoke() on the UI thread looks like a weird hack but is very useful. An excellent way to solve gritty re-entrancy problems.

Very simple, not the only way to do it. The main window's Load event could be a useful trigger.

Upvotes: 4

Glen Thomas
Glen Thomas

Reputation: 10764

Instead of having an image file with Build Action set to Splash Screen, you can have more control over the splash screen by creating and showing it yourself in the Application's OnStartup event handler. The show method of SplashScreen has a parameter to stop it closing automatically and then you can tell it when to close using the Close method:

Firstly remove the StartupUri tag from App.xaml:

<Application x:Class="Splash_Screen.App" 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Application.Resources> 

    </Application.Resources> 
</Application>

Change the Build Action of your image file to Resource

Then create and show the splash screen in the OnStartup event handler:

public partial class App : Application 
    { 
        private const int MINIMUM_SPLASH_TIME = 1500; // Miliseconds 
        private const int SPLASH_FADE_TIME = 500;     // Miliseconds 

        protected override void OnStartup(StartupEventArgs e) 
        { 
            // Step 1 - Load the splash screen 
            SplashScreen splash = new SplashScreen("splash.png"); 
            splash.Show(false, true); 

            // Step 2 - Start a stop watch 
            Stopwatch timer = new Stopwatch(); 
            timer.Start(); 

            // Step 3 - Load your windows but don't show it yet 
            base.OnStartup(e); 
            MainWindow main = new MainWindow(); 

            // Step 4 - Make sure that the splash screen lasts at least two seconds 
            timer.Stop(); 
            int remainingTimeToShowSplash = MINIMUM_SPLASH_TIME - (int)timer.ElapsedMilliseconds; 
            if (remainingTimeToShowSplash > 0) 
                Thread.Sleep(remainingTimeToShowSplash); 

            // Step 5 - show the page 
            splash.Close(TimeSpan.FromMilliseconds(SPLASH_FADE_TIME)); 
            main.Show(); 
        } 
    }

Upvotes: 2

Related Questions