2
votes

I am developing a project and I want to add to it a splash screen. I have checked questions here on Stackoverflow and other blogs and MSDN etc. but could not find the solution I am looking for.

I want my SplashScreen,

1- appear and stay on the screen 3-4 seconds but at the same time I want my Main Window NOT TO appear. When my splash screen fades out completely then Main Window should appear. Many of the examples I have checked out do not implement this. Even though I set SplashScreen.Close.(TimeSpan.FromMiliseconds(4000)) MainWindow still apeear immediately front or back of SplashScreen. They say "add an image to your project, make it's Build Action SplashScreen or Resource, if you want to handle fade out time go App.xaml.cs file and implement your own Main() method and put your logic." I know that already. It does not work.

2- If possible I want my splashscreen NOT TO fade out slowly. I want it to disappear suddenly.(if this is not possible or really hard for a intermediate developer to do it, it is ok. you may disregard.)

And please I want C# code not Xaml. My project is based on WPF adn .NET 4.0 client profile.

Thank you.

4
You're doing WPF and you don't want XAML?Henk Holterman
I mostly prefer C# code. I mean the answers that include both C# and Xaml would be perfect.msharpp

4 Answers

4
votes

Why don't you make your splash screen a fully qualified XAML <window> and in your App.xaml set it up as your StartupUri:

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

Then in your splash window's Load Event you initialize the main window (preferably somewhere else so the instance sticks around when you close the splash). From here you can also specify a timer for x-seconds to go off and show the main window / hide the splash window.

using System.Threading;

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

private Timer t;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    App.MainWindow = new MainWindow(); // Creates but wont show

    t = new Timer(new TimerCallback(CloseSplash), null, new TimeSpan(0,0,10), new TimeSpan(0,0,0,0,-1));

    // Do Other load stuff here?
}

private void CloseSplash(object info)
{
     // Dispatch to UI Thread
    Dispatcher.Invoke(DispatcherPriority.Normal, x => CloseSplashMain());
}

private void CloseSplashMain()
{
   App.MainWindow.Show()
   this.Close();
}

You'll have to change your app's main window behaviour though, otherwise closing the splash window will cause the app to close.

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        App.Current.ShutdownMode = ShutdownMode.OnLastWindowClose;
    }
}

Also don't forget to dispose your timer when you're done. It's an IDisposable and will keep firing that method unless it's stopped.

1
votes

There are answers but I find a an easier one. Just use the Thread.Sleep(int miliSeconds) method in the main window's constructor. This will delay your app in order to open specified miliseconds later.

0
votes

In the constructor of App.xaml.cs open your splash screen, wait for a few seconds, then close before proceeding with rest of the app. I am using Unity, so I close the splash screen somewhere after the Boostrapper has initialized some services.

 public partial class App : Application
    {
        private static SplashScreen _splashScreen;

        public App()
        {
            OpenSplashScreen();
            new Bootstrapper().Run(); 
        }

        private void OpenSplashScreen()
        {
            _splashScreen = new SplashScreen("SplashScreen/splash.jpg");
            _splashScreen.Show(false);
        }

        internal static void CloseSplashScreen(double time)
        {
            _splashScreen.Close(TimeSpan.FromSeconds(0));
            _splashScreen = null;
        }
    }

where Bootstrapper.cs is listed below:

public class Bootstrapper : UnityBootstrapper
    {
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
            var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
            section.Configure(Container);

           // initialize some services before

            App.CloseSplashScreen(0);

        }

        protected override IModuleEnumerator GetModuleEnumerator()
        {
            return new ExtendedConfigurationModuleEnumerator();
        }

        protected override DependencyObject CreateShell()
        {
            MainWindow shell = new MainWindow(Container);
            shell.Show();
            return shell;
        }
    }
0
votes

The best way and using the API is

  SplashScreen splash = new SplashScreen("splashscreen.jpg");
  splash.Show(false);
  splash.Close(TimeSpan.FromMilliseconds(2));
  InitializeComponent();