Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

display Hourglass when application is busy

Tags:

c#

wpf

For a view constructed using WPF, I want to change the mouse cursor to a hourglass when the application is busy and non-responsive.

One solution is to add

 this.Cursor = Cursors.Wait; 

to all the places that may cause the UI to become non-responsive. But obviously this is not the best solution. I am wondering what is the best way to achieve this?

Is it possible to achieve this by using Styles or Resources?

like image 560
sean717 Avatar asked Aug 13 '10 22:08

sean717


People also ask

Why is there an hourglass next to my cursor?

The Windows wait cursor, informally the Blue circle of death (known as the hourglass cursor until Windows Vista) is a cursor that indicates that an application is busy performing an operation. It can be accompanied by an arrow if the operation is being performed in the background.

What is a busy pointer?

The busy pointer is also called the hourglass. It means the computer is busy. The Capital "I" pointer is used in text processing program and search boxes. It is used to highlight blocks of text and to move the insertion point to another place in your documents.

How do you get rid of the hourglass on the computer?

Simultaneously press [Ctrl] [Alt] [Delete].

What is the use of busy shape of a mouse pointer?

Busy Pointer A busy pointer looks like an hourglass. The busy pointer lets you know there are other things going on in the background while you are trying to complete another task.


2 Answers

We did a disposable class that changes the cursor for us when the app is going to take long, it looks like this:

public class WaitCursor : IDisposable {     private Cursor _previousCursor;      public WaitCursor()     {         _previousCursor = Mouse.OverrideCursor;          Mouse.OverrideCursor = Cursors.Wait;     }      #region IDisposable Members      public void Dispose()     {         Mouse.OverrideCursor = _previousCursor;     }      #endregion } 

And we use it like this:

using(new WaitCursor()) {     // very long task } 

Might not be the greatest design, but it does the trick =)

like image 132
Carlo Avatar answered Sep 29 '22 18:09

Carlo


I used the answers here to build something that worked better for me. The problem is that when the using block in Carlo's answer finishes, the UI might actually still be busy databinding. There might be lazy-loaded data or events firing as a result of what was done in the block. In my case it sometimes took several seconds from the waitcursor disappeared until the UI was actually ready. I solved it by creating a helper method that sets the waitcursor and also takes care of setting up a timer that will automatically set the cursor back when the UI is ready. I can't be sure that this design will work in all cases, but it worked for me:

    /// <summary>     ///   Contains helper methods for UI, so far just one for showing a waitcursor     /// </summary>     public static class UiServices     {      /// <summary>     ///   A value indicating whether the UI is currently busy     /// </summary>     private static bool IsBusy;      /// <summary>     /// Sets the busystate as busy.     /// </summary>     public static void SetBusyState()     {         SetBusyState(true);     }      /// <summary>     /// Sets the busystate to busy or not busy.     /// </summary>     /// <param name="busy">if set to <c>true</c> the application is now busy.</param>         private static void SetBusyState(bool busy)         {             if (busy != IsBusy)             {                 IsBusy = busy;                 Mouse.OverrideCursor = busy ? Cursors.Wait : null;                  if (IsBusy)                 {                     new DispatcherTimer(TimeSpan.FromSeconds(0), DispatcherPriority.ApplicationIdle, dispatcherTimer_Tick, Application.Current.Dispatcher);                 }             }         }          /// <summary>         /// Handles the Tick event of the dispatcherTimer control.         /// </summary>         /// <param name="sender">The source of the event.</param>         /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>         private static void dispatcherTimer_Tick(object sender, EventArgs e)         {                 var dispatcherTimer = sender as DispatcherTimer;                 if (dispatcherTimer != null)                 {                     SetBusyState(false);                     dispatcherTimer.Stop();                 }         }     } 
like image 26
T.J.Kjaer Avatar answered Sep 29 '22 17:09

T.J.Kjaer