bsh152s
bsh152s

Reputation: 3218

How do I display wait cursor during a WPF application's startup?

Here are the basic events I want to happen when my WPF application starts. This is very similar to how Word starts on my machine.

  1. Display busy cursor.
  2. Perform basic initialization. This takes a couple of seconds and needs to be done before splash screen is displayed.
  3. Display splash screen. This splash screen displays progress into more in-depth initialization and can take awhile (caches information from database).
  4. Display default cursor. Since splash screen is displaying progress now, there's no need to display a busy cursor.
  5. Once splash screen progress is complete, display main window.
  6. Close splash screen.

Everything works fine except for the displaying of the busy cursor prior to the splash screen being displayed. When I execute the application through a shortcut, the wait cursor flashes, but soon goes back to the default. I've tried different ways to set the Cursor but none work, but I think the problem is that I'm not in a control/window--I'm doing it from within App.xaml.cs. And, the properties I'm setting seem to be Windows Forms properties. Here is an excerpt from my code in App.xaml.cs.

protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);

  System.Windows.Forms.Application.UseWaitCursor = true;
  //System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
  //System.Windows.Forms.Application.DoEvents();

  Initialize();

  SplashWindow splash = new SplashWindow();
  splash.Show();

  System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;

  // Right now I'm showing main window right after splash screen but I will eventually wait until splash screen closes.
  MainWindow main = new MainWindow();
  main.Show();
}

Upvotes: 33

Views: 77715

Answers (5)

Tanque
Tanque

Reputation: 315

For me it worked using a mix of the stuff stated above:

class MyForm : System.Windows.Window {}

class Test{
   MyForm myForm;

   void ShowWaitCurserInMyForm(){
      //before kicking off the stuff I'm waiting for: 
      System.Windows.Forms.Application.UseWaitCursor = true; // disables all Input from the mouse
      myForm.Cursor = System.Windows.Input.Cursors.Wait; // actually displays a wait Cursor

      // do time intensive stuff here, if we wait for an event, following stuff belongs in its handler

      System.Windows.Forms.Application.UseWaitCursor = false; // reenables all Input from the mouse
      myForm.Cursor = null; // reset the Cursor visually
   }
}

Upvotes: 0

user2069105
user2069105

Reputation: 621

If you have a task that takes a significant amount of time, and it is running on a non-GUI thread, (which is a good idea) you can use this code to change the application cursor:

Application.Current.Dispatcher.Invoke(() =>
{
    Mouse.OverrideCursor = Cursors.Wait;
});

When the busy process completes, use this:

Application.Current.Dispatcher.Invoke(() =>
{
    Mouse.OverrideCursor = null;
});

Upvotes: 54

Bianca Kalman
Bianca Kalman

Reputation: 229

        Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
        InitializeComponent();
        ...
        Mouse.OverrideCursor = null;

Upvotes: 5

Nathan Strong
Nathan Strong

Reputation: 2400

I'm assuming the Initialize() is the part that you want your busy cursor to appear for, yes?

If so, try the following approach:

  1. In your MainWindow.xaml, on the <Window> element, set the following properties: Visibility="Hidden" and Cursor="Wait".
  2. In your MainWindow.xaml.cs, move the initialization code out of the constructor and into a public Initialize() method, so that any code that depends on the Initialize() call doesn't get executed. Make sure the end of your Initialize() method sets the Visiblity property to Visible and resets the Cursor as well.
  3. Update the code snippet posted above to something like the following:
protected override void OnStartup(StartupEventArgs e)
{
  base.OnStartup(e);

  MainWindow main = new MainWindow();
  main.Show(); // this should set the cursor how you want it
  Initialize();
  SplashWindow splash = new SplashWindow();
  splash.Show();
  main.Initialize(); // now invoke the Initialize method you created
  // Right now I'm showing main window right after splash screen but I will eventually wait until splash screen closes.
}

Upvotes: 2

Kevin DiTraglia
Kevin DiTraglia

Reputation: 26058

This should work

Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;

Use System.Windows.Input not System.Windows.Forms.

Upvotes: 67

Related Questions