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

ProgressWorker

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.22/5 (11投票s)

2009年3月13日

CPOL

3分钟阅读

viewsIcon

50016

downloadIcon

1588

一个带有 BackgroundWorker 包装器的 WinForms 进度条控件。

为什么?

在我的许多项目中,我使用后台工作线程来执行后台任务。有很多不同的场景可以使用它。它们都有一个共同点(或者几乎都有):我将它与进度条链接起来,以便向用户显示正在发生某些事情。

即使这是一个简单的过程,我厌倦了每次需要将其添加到项目中时都输入(或复制/粘贴)相同的代码,所以我最终将两者结合在一起。

这是什么?

所以,这就是 ProgressWorker。它没有什么了不起的复杂性,但我发现它很有用,所以我认为我会与 CodeProject 社区分享它。

该类派生自 System.Windows.Forms.ProgressBar,并且还是 System.ComponentModel.BackgroundWorker 的包装器。

有什么不同?

你必须有风格!

标准进度条有三种显示样式。其中两种显示递增的条,另一种 (Marquee) 显示一个从左到右“弹跳”的条 永无止境。 后者最适用于无法量化进度但需要指示正在进行活动的情况。 为了使这种选择更加自动化,Style 属性现在只有 BlockContinuous。 如果 ReportsProgress 属性为 false,则为基本类的 Style 选择 MarqueeMarquee 样式的问题在于它会一直持续,即使您不希望它持续,因此只有在工作线程开始工作时才应用此样式。

没有限制

进度条通常允许您设置自己的最小值和最大值。 我已将这些固定为 0 和 100,以便它可以很好地与工作线程的 ReportProgress 配合使用,并且它们是只读的。

它价值多少?

现在 Value 属性是只读的,因为它应该只由工作线程更新。

多余的要求

不需要 Step 属性、PerformStepIncrement 方法,所以我已尽我所能地隐藏了它们。

继承说明

从基类继承时,您应该添加功能,而不是删除功能。 因此,并非所有内容都可以隐藏,并且无论您应用什么属性,都会显示在 intellisense 中。 微软说这是故意的,并且是正确的 OOP 方式 #(即使他们自己隐藏了很多东西!),但我真的不喜欢必须从 IWin32Window 开始并从头开始构建所有内容

我主要在更改的内容上使用了 new 而不是 override。 例如,重写不允许您将读/写属性转换为只读属性。 所以,在任何人因此而攻击我之前,这是故意的!

有什么新功能?

... 好吧,不多。 现有的控件和组件拥有所需的一切,这只是将它们结合到一个方便的控件中。 噢,我添加了一个 Reset 方法,它会将 Value 设置回零并在适用的情况下停止 Marquee 样式。

我更改了一些“包装”名称以删除工作线程引用。 除此之外,您会找到所有正常的进度条和后台工作线程内容,因此使用起来应该非常直观。 如果不是(或者您从未用过后台工作线程),则附加了一个演示。

代码在哪里?

在我因撰写一篇没有代码的文章而被抨击之前...! 实际上并没有什么有趣的,因为它(如前所述)只是带有包装的后台工作线程的进度条的派生。 这是一个演示的主窗体中实现的少量代码转储,以显示它的易用程度

public partial class FormMain : Form
{
    public FormMain()
    {
        InitializeComponent();
        progressWorker.DoWork += 
          new System.ComponentModel.DoWorkEventHandler(progressWorker_DoWork);
        progressWorker.ProgressChanged += 
          new System.ComponentModel.ProgressChangedEventHandler(
          progressWorker_ProgressChanged);
        progressWorker.RunCompleted += 
          new System.ComponentModel.RunWorkerCompletedEventHandler(
          progressWorker_RunCompleted);
        richTextBox.SelectAll();
    }

    private void progressWorker_DoWork(object sender, 
                 System.ComponentModel.DoWorkEventArgs e)
    {
        for (int i = 1; i <= 100; i++)
        {
            if (progressWorker.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
            // simulate long operation
            System.Threading.Thread.Sleep(50);
            progressWorker.ReportProgress(i);
        }
    }

    private void progressWorker_ProgressChanged(object sender, 
            System.ComponentModel.ProgressChangedEventArgs e)
    {
        Console.WriteLine(e.ProgressPercentage);
    }

    private void progressWorker_RunCompleted(object sender, 
            System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
        button.Text = "&Start ProgressWorker";
        button.Enabled = true;
        progressWorker.Reset();
    }

    private void button_Click(object sender, EventArgs e)
    {
        if (progressWorker.IsBusy)
        {
            button.Enabled = false;
            progressWorker.CancelAsync();
        }
        else // start
        {
            progressWorker.RunAsync();
            button.Text = "&Cancel ProgressWorker";
        }
    }

    private void checkBox_CheckedChanged(object sender, EventArgs e)
    {
        progressWorker.ReportsProgress = checkBox.Checked;
    }
}

参考文献

历史

  • 2009 年 3 月 13 日:初始版本。
© . All rights reserved.