Reputation: 832
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
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
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