Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Display Loading Indicator in Windows Form Application

0.00/5 (No votes)
7 Dec 2017 1  
This article explains how to display a loading indicator (a GIF image) in Windows Forms application when some long running task is performed in the background.

Introduction

If your Windows Form application is doing some long running tasks in the background, then the UI becomes unresponsive. To inform the user that some long running task is operating in the background, you need to display an indicator. The indicator can be as simple as an animated image (GIF image). This article describes how to do the same in Windows Forms. 

The example provided in this article displays the number of vowels, consonants, numbers and special characters present in a text file. It reads the input from a text file line by line which is provided by the user and displays the output in a grid.

Design the Form

Create a new Windows Form project in Visual Studio.

Create Windows Form Project

Drag and drop the Label, Button, ComboBox and DataGridView controls in the Windows Form to create a form similar to the displayed below:

Design Form

Add a PictureBox control to the centre of the form and then set the "Image" and "InitialImage" properties to the loading image. You can import the image from the Visual Studio Properties Window. To do the same, click the "..." button displayed next to the "Initial Image" value. It will open the "Select Resource" window.  Choose the "Project resource file" option and then click the "Import..." button. Choose the loading image and then click "Open" and "Ok" buttons. Repeat the same process to set the "Image" property of the PictureBox control. See the below images for reference.

Import Image

Core Functionality

When the user clicks the "Find" button, we want to display a loading indicator to the user so the user can know that the operation is happening in the background. The loading indicator is displayed as follows:

Loading Indicator

After the background operation is completed, the loading image is hidden and the data are loaded to the grid. Below is a screenshot of the form where data are loaded to the grid.

Result

Using the Code

Display Dialog

When the user clicks the "Browse.." button, we want to display a dialog from where the text file will be selected. The below code is used to display the file open dialog with the customization. Note the "Title" and "Filter" added to the file open dialog.

var dialog = new OpenFileDialog();
dialog.Title = "Browse Text Files";
dialog.DefaultExt = "txt";
dialog.CheckFileExists = true;
dialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
dialog.Multiselect = false;

dialog.ShowDialog();

var fileName = dialog.FileName;
txtFilePath.Text = fileName;

Display Loading Indicator

private void SetLoading(bool displayLoader)
{
    if (displayLoader)
    {
        this.Invoke((MethodInvoker)delegate
        {
            picLoader.Visible = true;
            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
        });
    }
    else
    {
        this.Invoke((MethodInvoker)delegate
        {
            picLoader.Visible = false;
            this.Cursor = System.Windows.Forms.Cursors.Default;
        });
    }
}

The above code is used for displaying the loading image which is kept inside a PictureBox control. Note that the code is kept inside this.Invoke(); When the loading image is displayed, the cursor is changed to "wait" cursor.

Releasing the UI Thread

To keep the UI responsive, the whole operation takes place in a new thread.

private void btnFind_Click(object sender, EventArgs e)
{
    try
    {
        Thread threadInput = new Thread(DisplayData);
        threadInput.Start();
    }
    catch (Exception ex)
    {
        DisplayError(ex);
    }
}

The DisplayData() method performs all operations like calling a method to show/hide loading image, read from the file, find characters and bind the grid.

private void DisplayData()
{
    SetLoading(true);
    
    // Do other operations...

    SetLoading(false);
}

The first line displays the loading indicator. The other operation takes place next and finally, the loading indicator is hidden.

Reading Data from Controls

We cannot read the data from the controls directly because the whole operation takes place in a separate thread. If you will try to read the content from the control directly, then it will throw an error.

If you will try to read the ComboBox value directly in the DisplayData() method, then it will throw invalid cross-thread operation error.

var charType = cmbCharacterType.Text;
InvalidOperationException:

Cross-thread operation not valid: Control 'cmbCharacterType' accessed from a thread other than the thread it was created on.

The data is read from the controls as follows:

this.Invoke((MethodInvoker)delegate
{
    charType = cmbCharacterType.Text;
                    
    path = txtFilePath.Text.Trim();
});

History

  • 7th December, 2017: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here