C# WaitCursor while form loads

26,501

Solution 1

Why do you have to remove the this.Visible = false? You should still be able to do it while setting the cursor.

Would it be an acceptable solution to have the ResultsForm set the cursor instead of the parent form? Get it to set the cursor before it starts the code that takes all the time, then set it back at the end.

Solution 2

It forces me to disable the MainForm hiding feature which I would like to retain.

You should be able to do both, without issues.

It increases coupling since Cursor.Current = Cursor.Default; needs to be called within the ResultsForm Shown event

Have you tried putting your cursor logic entirely into the ResultsForm dialog code? You should be able to set Cursor.Current = Cursors.WaitCursor; inside of the ResultsForm's constructor, and then have Cursor.Current = Cursor.Default; set inside of the Shown event.

This would keep the logic entirely in the dialog, and out of the main window. You could also then keep the visibility toggling in the main window.

Solution 3

If you always want to display a wait cursor when loading this form (regardless of whether it's shown from), then, as Reed suggests, you should just do it in the form itself.

However, if you only need the cursor in this one particular case of displaying a form, then you can use a lambda (or anonymous delegate, if you're dealing with C# 2.0) for an event handler:

using (ResultsForm frm = new ResultsForm())
{
    this.Visible = false;

    var oldCursor = Cursor.Current;
    Action<object, EventArgs> restoreCursor = 
        delegate
        {
            Cursor.Current = oldCursor;
            frm.Shown -= restoreCursor;
        };
    frm.Shown += restoreCursor;

    Cursor.Current  = Cursor.WaitCursor
    frm.ShowDialog();
}

Solution 4

The cursor will change to WaitCursor but that will survive only a fraction of a second. The problem is that hiding your main form makes the cursor overlap the window that's behind your main form. Or the desktop. The revealed window gets a WM_SETCURSOR message from Windows and it will change the cursor to its preferred shape.

But there's a bigger problem with your approach. After the dialog closes, there's a fraction of a second where no window in your app is visible. Windows is forced to find another window to give the focus to, it won't be a window in your app. When your main form again becomes visible, it may well end up behind the window that got the focus. This behavior tends to be a bit flaky, you might not yet have found it.

You can solve both problems by hiding the window a different way:

  this.Opacity = 0.01;
Share:
26,501
Alexandre Bell
Author by

Alexandre Bell

Interested in C++, Erlang, Python, SQL and related topics. Have been programming since the 80s when I got a ZX Spectrum and started learning BASIC and later Machine Code.

Updated on December 01, 2020

Comments

  • Alexandre Bell
    Alexandre Bell over 3 years

    I'm having a form that takes a few seconds to finally display. This form is called through:

    using (ResultsForm frm = new ResultsForm())
    {
        this.Visible = false;
        frm.ShowDialog();
        this.Visible = true;
    }
    

    It's useful that I get the default cursor to Cursors.WaitCursor while waiting for the form to finally display. Currently I can only seem to be able to do this successfully by using the static 'Current' property:

    using (ResultsForm frm = new ResultsForm())
    {
        //this.Visible = false;
        Cursor.Current = Cursors.WaitCursor;
        frm.ShowDialog();
        //this.Visible = true;
    }
    

    But this has two problems:

    • It forces me to disable the MainForm hiding feature which I would like to retain.
    • It increases coupling since Cursor.Current = Cursor.Default; needs to be called within the ResultsForm Shown event.

    How can I change the Cursor while the form loads without changing the first code snippet and while avoiding coupling?

    UPDATE: Now the question was answered, video presentation was removed so I don't go over my ISP bandwidth limitations.