Show loading window

12,167

Solution 1

You should look at this MSDN article on creating a SplashScreen in WPF. Essentially you add the Image you want to show to your project and set the Build Action to SplashScreen it will show when your program starts and disappear when your Main Application Window is shown.


You could also try importing the System.ComponentModel Class and use BackgroundWorker to Show your Loading Form, it will allow you to retain responsiveness of your UI.

public partial class MainWindow : Window
{
    Window1 splash;
    BackgroundWorker bg;
    public MainWindow()
    {

        InitializeComponent();

        bg = new BackgroundWorker();
        bg.DoWork += new DoWorkEventHandler(bg_DoWork);
        bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);

    }

    void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        splash.Hide();
    }

    void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        System.Threading.Thread.Sleep(10000);
    }


    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        splash = new Window1();
        splash.Show();
        bg.RunWorkerAsync();
    }
}

Solution 2

You should put your time consuming code in a background thread (for that you can use BackgroundWorker, Task or Async Await, depending on your dot net framework version)

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    LoadForm lf = new LoadForm();
    lf.Visibility = Visibility.Visible;
    //start the time consuming task in another thread
}


HeavyTaskCompleteEvent()
{
     lf.Close();
}

Also look out for the best way to show loading screen. You can show some animation in the main window as well. I don't think showing a form is the best way.

Solution 3

I made a Loader class a while ago you could use. It shows a Window while doing your loading-method, closes it when completed and gives you the output of the method:

public class Loader<TActionResult>:FrameworkElement
{
    private Func<TActionResult> _execute;
    public TActionResult Result { get; private set; }
    public delegate void OnJobFinished(object sender, TActionResult result);
    public event OnJobFinished JobFinished;

    public Loader(Func<TActionResult> execute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
    }

    private Window GetWaitWindow()
    {
        Window waitWindow = new Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None };
        waitWindow.Content = new TextBlock { Text = "Please Wait", FontSize = 30, FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };

        return waitWindow;
    }

    public void Load(Window waitWindow = null)
    {
        if (waitWindow == null)
        {
            waitWindow = GetWaitWindow();
        }
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += delegate
        {
            Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); }));
            Result = _execute();
            Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); }));
        };
        worker.RunWorkerCompleted += delegate
        {
            worker.Dispose();
            if (JobFinished != null)
            {
                JobFinished(this, Result);
            }
        };
        worker.RunWorkerAsync();
    }
}

How to use it:

Loader<TResult> loader = new Loader<TResult>(MethodName);
loader.JobFinished += new Loader<TResult>.OnJobFinished(loader_JobFinished);
loader.Load();

void loader_JobFinished(object sender, TResult result)
{
    // do whatever you want with your result here
}
Share:
12,167
FukYouAll
Author by

FukYouAll

These sites used to be a great help, but now are full of annoying, bitter and lifeless people looking for badges and reporting everything because they hate their lifes!

Updated on June 13, 2022

Comments

  • FukYouAll
    FukYouAll almost 2 years

    My application in WPF loads external resources, so I want to show a loading form while the program is loading.

    I tried to create the form, and show before the loading code, and close when loading ended.

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
         LoadForm lf = new LoadForm();
         lf.Visibility = Visibility.Visible;
    
         // Al code that delays application loading
    
         lf.Close();
    }
    

    But the only thing I get is that the form is showed when loading progress is complete and immediately closes.

    I think that I need to use System.Threading but not sure.

    Thanks.

    Note I load all application external resources in Window_Loaded() method and not in the main class method.