Tuesday, July 31, 2012

Wait Cursors

Ah, cursor management, the bane of desktop programmers everywhere. Truth be told, .NET makes it quite easy to swap between cursor styles, the most common is to alert the user that the application is waiting on a long running task. Usually you see code like this:

private void cmdSave_Click(object sender, EventArgs e)
    {
        Cursor.Current = Cursors.WaitCursor;
            
        // Do Stuff Here...

        Cursor.Current = Cursors.Default;
    }

Very straight forward, but wait! What if we want to have multiple exit points in our logic? Then  we end up with something like this:

private void cmdSave_Click(object sender, EventArgs e)
    {
        Cursor.Current = Cursors.WaitCursor;
            
        // Do Stuff Here...

        if (done == true)
        {
            Cursor.Current = Cursors.Default;
            return;
        }
            
        // Do Stuff Here...

        if (done == true)
        {
            Cursor.Current = Cursors.Default;
            return;
        }

        Cursor.Current = Cursors.Default;
    }

This is obviously prone to error, if for example we forget to add an assignment to set the cursor back prior to exiting, or we hit an error and forget to put the cursor back to default in a try/catch block we can end up with the never ending wait cursor.

But Rob, you ask, what can be done? Never fear I am here with your very own WaitCursor class that will automagically fix these issues for you. Here is the code:

public class WaitCursor : IDisposable
    {
        private readonly Cursor _originalCursor = Cursors.Default;

        public WaitCursor()
        {
            _originalCursor = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
        }

        public WaitCursor(Cursor cursor)
        {
            _originalCursor = Cursor.Current;
            Cursor.Current = cursor;
        }

        #region IDisposable Members

        private bool _disposed;

        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
                return;
            
            if (disposing)
                Cursor.Current = _originalCursor;

            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }


As you can see when instantiated, we grab the current cursor state, then set the current cursor to either the wait cursor, or whatever cursor we have passed in. When the class gets disposed, we set the cursor back to the original cursor. This allows us to write code like this:

private void cmdSave_Click(object sender, EventArgs e)
    {
        using (new WaitCursor())
        {
            // Do Stuff Here...

            if (done == true)
                return;
            
            // Do Stuff Here...

            if (done == true)
                return;
        }
    }

You are welcome

Thursday, July 19, 2012

Internet Defense League

Code Refugee is proud to be a member of The Internet Defense League. Ever since the US Government tried to foist the tragically draconian SOPA/PIPA censorship laws on the world, a number of organizations (Reddit, Fark, Imgur, TechDirt) have come together to found an organization to raise awareness of threats to internet freedom. There can be no more critical fight for the future of our world than the one to keep our most important communication mechanism free from governmental interference. Today the league has officially launched and we are showing the "cat signal" in recognition.

Please take a few minutes to familiarize yourself with the league and its goals. I think you will find them worthy of your attention.