John Dunn

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







Re: Windows Presentation Foundation (WPF) Showing status during Application startup

WPCoder

For a simple implementation (and assuming you don't need to do fancy stuff with the UI while it's loading) I'd kick off the load by passing the file name as an argument to your main form. Then in your main form's constructor, create a new Thread and load it within that thread. When it's done, use the dispatcher to inform the UI that it's done. You can display a "loading" message while it's waiting for the 'signal' to be received that the file is done.






Re: Windows Presentation Foundation (WPF) Showing status during Application startup

John Dunn

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.




Re: Windows Presentation Foundation (WPF) Showing status during Application startup

ivolved_Mike_Brown

The trick is to do the splash screen and the file loading before you show your main form. You can do this in App.OnStartup. Create a splash screen window and have App.OnStartup call ShowDialog() on that screen. Make the Window.Loaded handler for your splash screen do all the initialization. When it's done it closes and control returns to App.OnStartup which then calls Base.OnStartup to continue starting the app.






Re: Windows Presentation Foundation (WPF) Showing status during Application startup

John Dunn

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);
}
}
}






Re: Windows Presentation Foundation (WPF) Showing status during Application startup

ivolved_Mike_Brown

What if you did a While loop that checked a boolean on splash. If it's true sleep for 500 ms . When the splash is finished loading, set it to false and then close it. I've got code somewhere that did the splash screen before .Net 2.0 provided one natively...I'll dig it up and share with you. It more or less does the same thing that the Winforms splash does.






Re: Windows Presentation Foundation (WPF) Showing status during Application startup

John Dunn

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.