65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Windows 窗体应用程序中显示加载指示器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2017 年 12 月 7 日

CPOL

3分钟阅读

viewsIcon

122155

downloadIcon

6067

本文介绍了如何在 Windows Forms 应用程序中显示加载指示器(GIF 图像),当后台执行一些长时间运行的任务时。

引言

如果您的 Windows Form 应用程序正在后台执行一些长时间运行的任务,那么用户界面会变得无响应。 为了告知用户某些长时间运行的任务正在后台运行,您需要显示一个指示器。 该指示器可以像动画图像(GIF 图像)一样简单。 本文介绍如何在 Windows Forms 中执行相同的操作。

本文提供的示例显示了文本文件中存在的元音、辅音、数字和特殊字符的数量。 它逐行读取用户提供的文本文件中的输入,并在网格中显示输出。

设计窗体

在 Visual Studio 中创建一个新的 Windows Form 项目。

Create Windows Form Project

LabelButtonComboBoxDataGridView 控件拖放到 Windows Form 中,以创建一个类似于下面显示的窗体

Design Form

PictureBox 控件添加到窗体中心,然后将“Image”和“InitialImage”属性设置为加载图像。 您可以从 Visual Studio 属性窗口导入图像。 为此,请单击“初始图像”值旁边显示的“...”按钮。 这将打开“选择资源”窗口。 选择“项目资源文件”选项,然后单击“导入...”按钮。 选择加载图像,然后单击“打开”和“确定”按钮。 重复相同的过程来设置 PictureBox 控件的“Image”属性。 请参考下图。

Import Image

核心功能

当用户单击“查找”按钮时,我们希望向用户显示一个加载指示器,以便用户可以知道该操作正在后台进行。 加载指示器显示如下

Loading Indicator

后台操作完成后,加载图像将被隐藏,并将数据加载到网格中。 下面是将数据加载到网格中的窗体的屏幕截图。

Result

Using the Code

显示对话框

当用户单击“浏览..”按钮时,我们希望显示一个对话框,从中选择文本文件。 以下代码用于显示具有自定义设置的文件打开对话框。 注意添加到文件打开对话框的“Title”和“Filter”。

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;

显示加载指示器

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;
        });
    }
}

上面的代码用于显示保存在 PictureBox 控件中的加载图像。 请注意,该代码保存在 this.Invoke(); 内部。 显示加载图像时,光标将更改为“wait”光标。

释放 UI 线程

为了保持 UI 的响应性,整个操作在一个新线程中进行。

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

DisplayData() 方法执行所有操作,例如调用方法来显示/隐藏加载图像、从文件读取、查找字符和绑定网格。

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

    SetLoading(false);
}

第一行显示加载指示器。 下一步执行其他操作,最后隐藏加载指示器。

从控件读取数据

我们无法直接从控件读取数据,因为整个操作是在一个单独的线程中进行的。 如果您尝试直接从控件读取内容,则会引发错误。

如果您尝试直接在 DisplayData() 方法中读取 ComboBox 值,则会引发无效的跨线程操作错误。

var charType = cmbCharacterType.Text;
InvalidOperationException

跨线程操作无效:从创建控件的线程以外的线程访问控件“cmbCharacterType”。

从控件读取数据的方式如下

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

历史

  • 2017 年 12 月 7 日:初始版本
© . All rights reserved.