Hourglass problem in a WinForm application

17k views Asked by At

In my program with a UI in WinForm. I set the cursor to a hourglass just before to launch a method in ThreadPool.

My code in UI thread to set the cursor looks like this :

Application.UseWaitCursor = true;

When the method is finished, i go back to the UI Thread to set the cursor to the normal case.

Application.UseWaitCursor = false;

My problem is the cursor stay to the Hourglass till I don't move the mouse. It's a little bit disturbing if the user wait on the end of the action without moving the mouse.

Anyone can help me ?

Jérôme

6

There are 6 answers

1
codingbadger On BEST ANSWER

I am unable to reproduce this behaviour? It works fine for me.

One thing to note though if you use the Control.Cursor = Cursors.WaitCursor approach is that it usually used like so:

this.Cursor = Cursors.WaitCursor

Which would appear to work fine, however, this refers the form so if the user moves the mouse to a different control, e.g a TextBox then the mouse does not show the wait cursor.

This may cause confusion for the users. Or could cause some issues if the user continues to work on something else when the Application is busy doing other work.

0
Olivier Jacot-Descombes On

A reusable solution is to use a little disposable helper class.

public sealed class WaitCursor : IDisposable
{
    public WaitCursor()
    {
        Application.UseWaitCursor = true;
        Cursor.Current = Cursors.WaitCursor;
    }

    public void Dispose()
    {
        Application.UseWaitCursor = false;
        Cursor.Current = Cursors.Default;
    }
}

With C#'s using var usage becomes very easy (example):

using var waitCursor = new WaitCursor();

using var dbContext = new MyDbContext();
await dbContext.Adresses.LoadAsync();
var adresses = _dbContext.Adressen.Local.ToBindingList();
gridControl1.DataSource = adresses;

The default cursor will be restored automatically at the end of the current code block. No need for an explicit try-finally to make the code safe.

0
Gilberto Soares On

My solution....

public class SetMouseCursor
{
    public static void Wait()
    {
        Application.UseWaitCursor = true;
        Cursor.Current = Cursors.WaitCursor;
    }

    public static void Default()
    {
        Application.UseWaitCursor = false;
        Cursor.Current = Cursors.Default;
    }
}
2
Jakub Kaleta On

Actually, there is one more way to do it, which I found somewhere after hours of researching this problem.

Unfortunately, it is a hack.

Below is a method that I wrote that handles the problem.

/// <summary>
    /// Call to toggle between the current cursor and the wait cursor
    /// </summary>
    /// <param name="control">The calling control.</param>
    /// <param name="toggleWaitCursorOn">True for wait cursor, false for default.</param>
    public static void UseWaitCursor(this Control control, bool toggleWaitCursorOn)
    {
        ...

        control.UseWaitCursor = toggleWaitCursorOn;

        // Because of a weird quirk in .NET, just setting UseWaitCursor to false does not work
        // until the cursor's position changes. The following line of code fakes that and 
        // effectively forces the cursor to switch back  from the wait cursor to default.
        if (!toggleWaitCursorOn)
            Cursor.Position = Cursor.Position;
    }
3
leppie On

Set the cursor manually. That's what I do.

2
26071986 On

One more way:

Cursor.Current = Cursors.WaitCursor;

When finished, just change the cursor back:

Cursor.Current = Cursors.Default;