
If you are faced with programming in .net, you probably noticed that when you start a program written using WPF, nothing happens for a long time. This lasts about 10 seconds, and then the main application window opens. Even launching an empty WPF application template takes about two seconds.
This pause introduces uncertainty in the perception of the program by the user: did the program start or not?
You can solve this problem by showing the splash screen immediately after launch. This will give a physical response immediately after launching the application and create the illusion of faster loading.
')
How to do this is written under the cut.
Why does the application load so long
This is due to the fact that when you run Windows .net libraries, which occupy about 20 megabytes, are not loaded into memory. The .net Framework dynamically loads the necessary libraries at program startup. If we look at the Output in the studio when the program starts, then we can see it:
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_32 \ mscorlib \ 2.0.0.0___b77a5c561934e089 \ mscorlib.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SplashDemo .vshost.exe' (Managed): Loaded Module is optimized and the debugger option 'Just My Code' is enabled.
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ PresentationFramework \ 3.0.0.0__31bf3856ad364e35 \ PresentationFramework.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
...
...
...
'SplashDemo.vshost.exe' (Managed): Loaded 'D: \ work \ Visual Studio 2008 \ Projects \ SplashDemo \ bin \ Debug \ SplashDemo.exe', Symbols loaded.
Step into: Stepping over non-user code 'System.Windows.SplashScreen.SplashScreen'
Step into: Stepping over non-user code 'SplashDemo.App.App'
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ System.Configuration \ 2.0.0.0__b03f5f7f11d50a3a \ System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Step into: Stepping over non-user code 'SplashDemo.App.InitializeComponent'
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ PresentationFramework.Aero \ 3.0.0.0____bf3856ad364e35 \ PresentationFramework.Aero.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
How this was solved before
It was necessary to dance with a tambourine and run the native code before starting the application. And then somehow stop it. The commercial component
Quicksplash offers to delete the file from the specified folder after downloading your application. The option is somewhat uncomfortable. The rest is even worse.
How it is solved now
With the advent of .net 3.5 sp1, everything is done with literally two mouse clicks. Only images in the following formats are supported: BMP, GIF, JPEG, PNG and TIFF. PNG has support for alpha channel.
Option number 1
The easiest option. It is sufficient in 99% of cases. To create a splash screen, add an image to the project:

And in the
Properties window of the added file, set the
Build Action parameter to the value of
SplashScreen .

This is all that is needed.
During the build, the following lines will be added to the
App.g.cs file:
SplashScreen splashScreen = new SplashScreen( "splash.png" );
splashScreen.Show( true );
* This source code was highlighted with Source Code Highlighter .
We will analyze them a bit later.
Option number 2a
The second option is not much different from the first: we will just do everything with our own hands. To do this, add a picture to the project. Open
App.xaml (not
App.xaml.cs ) and add a new handler for the StartUp event:

Go to the
App.xaml.cs file, look for the newly created method and supplement it with the following lines:
private void AppStartUp( object sender, StartupEventArgs e)
{
var splash = new SplashScreen( "splash.png" );
splash.Show( true );
}
* This source code was highlighted with Source Code Highlighter .
Let's take them apart. The first line creates a new instance of the SplashScreen class. The constructor has a single parameter — the file name:
var splash = new SplashScreen( "splash.png" );
* This source code was highlighted with Source Code Highlighter .
In the second line, we call the
Show method
(bool autoClose) . If the argument value is true, then the screen saver will close automatically after the application is loaded. Otherwise, you must call the
Close method.
splash.Show( true );
* This source code was highlighted with Source Code Highlighter .
Option number 2b
Practice has shown that there are situations when it is necessary to show the screensaver not only when loading, but also, for example, immediately after the authorization window:
public Window1()
{
ShowAuthorizationDialog();
InitializeComponent();
}
* This source code was highlighted with Source Code Highlighter .
Due to the fact that
InitializeComponent () is called after authorization, there is an additional load of libraries that are used in the code of the main application, but are not used in the authorization window. This causes a delay before the main window appears. In order to avoid this effect, you can do the following:
public Window1()
{
ShowAuthorizationDialog();
var splash = new SplashScreen( "spalsh.png" );
splash.Show( false );
InitializeComponent();
splash.Close( TimeSpan .FromMinutes(0.5));
}
* This source code was highlighted with Source Code Highlighter .
Here is the only new line:
splash.Close( TimeSpan .FromMinutes(0.5));
* This source code was highlighted with Source Code Highlighter .
The
Close () method closes the splash screen with a fade effect. As a parameter, the method takes a time interval during which the splash screen will “go out”.
Known bugs
In the process of using a couple of times skipped a black background instead of transparency. The reasons have not yet revealed.
Win32Exeption occurs when switching to another application at the moment when the screen saver goes out. You can catch surrounding the
Close () method with a
try ... catch block .
Conclusion
Using the screensaver in your program makes it cozier and more human to the user. Allows you to avoid unnecessary mental aggression towards the developer. :-)
UPD: This only applies to WPF applications.
UPD2: Moved to
.NET blog. Thank.