Showing status during Application startup
I'm having a problem figuring out how to best give my user feedback when loading a large file into my application. If the user double clicks on a file the application is launched with it's argument being the file to load. The problem is that with my current implementation, the entire file is loaded before anything is displayed to the user. Obviously this isn't the best experience but looking through the documentation it's not clear to me what would work better.
Here's how I currently have it working
* App.OnStartup : this loads the file from disk and stashes the root. This may take a while in some cases.
* MainWindow.ctor() : calls InitializeComponent and then creates a new viewer, pointed at the root.
* viewer.ctor() : iterates what was loaded from disk, creating DrawingVisual objects as required. This can take some time as well.
The first thing I tried was showing a startup ( splash ) window during App.OnStartup(), telling the user that the app is loading from disk. This works ok but if I call Close() on that window at the end of App.Startup() my main window is never shown and the app exits.
I think I'd like to delay loading anything from disk until my main window is shown. I could then popup a dialog while the file is being loaded from disk. Worst case I'd then set the cursor to the wait cursor while the viewer was loading - I'm guessing there's some threading issues with trying to show status while this is happening.
Every event I've tried to hook occurs before my window is up and running. Is there some event I'm missing that will work for what I'm trying to do?
Thanks for the reply.
I'm having problems figuring out when to show my 'loading' dialog. I'd like to wait until my main window is up and running, display a status dialog, and then launch a thread to start the load but I can't seem to find a Window event to hook to. If I try an create my status dialog in either the constructor for my window or within Window.OnInitialized an exception is thrown telling me I cannot set Owner property to a Window that has not been shown previously.
I've searched through the SDK but I can't seem to figure out how to wait to run something until my main window is up and running. I think I need to set the Owner property and show the status window modally ( ShowDialog ) so the user can't interact with the app until it's done loading.
I'm getting some weird results. If I call ShowDialog on my window from within OnStartup my main window is never shown. If I just call Show then my main window displays but it doesn't wait for my load to finish.
I even tried creating a System.Threading.EventWaitHandle which would be triggered from my load thread but that also causes the main window to not display either.
Here's the code I'm trying to use
Code Snippet
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Xml;
namespace WPFApplication1
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
delegate void MyDelegate();
protected override void OnStartup(StartupEventArgs e)
{
SplashWindow splash = new SplashWindow();
System.Threading.Thread th = new System.Threading.Thread(
delegate()
{
// lets wait 5 seconds and then close the splash window
System.Threading.Thread.Sleep(5000);
splash.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
(MyDelegate)delegate()
{
splash.Close();
}
);
}
);
th.Start();
// this works but return immediately
splash.Show();
// this doesn't work but blocks until dialog returns
// splash.ShowDialog();
base.OnStartup(e);
}
}
}
Calling System.Threading.Thread.Sleep() makes the splash window unresponsive and stop painting itself.
I've figured out a solution that works but is not ideal. If I make the StartupUri to be my splash window and on it's OnClosing create my new main window, it works. The only problem I have with this solution is that if the user is not loading a file I'd rather not show any splash window at all - it's only really necessary during a file load. Perhaps it's possible to change the StarupUri from code based on the arguments.
Code Snippet
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace WPFApplication1
{
/// <summary>
/// Interaction logic for SplashWindow.xaml
/// </summary>
delegate void MyDelegate();
public partial class SplashWindow : Window
{
public SplashWindow()
{
InitializeComponent();
// launch thread to open flie
System.Threading.Thread th = new System.Threading.Thread(
delegate()
{
// lets wait 5 seconds and then close the splash window
System.Threading.Thread.Sleep(5000);
done = true;
this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
(MyDelegate)delegate()
{
this.Close();
}
);
}
);
th.Start();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
Window1 win = new Window1();
App.Current.MainWindow = win;
win.Show();
base.OnClosing(e);
}
}
}
Does anyone else have issues trying to use the code snippet tool? It always messes up my posts. I'm using Firefox if that matters.