当前位置: 首页 > 知识库问答 >
问题:

如何使用WinForms进度条?

卫高明
2023-03-14

我想展示在外部库中执行的计算的进度。

例如,如果我有一些计算方法,我想在我的Form类中为100000个值使用它,我可以写:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }            

    private void Caluculate(int i)
    {
        double pow = Math.Pow(i, i);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        progressBar1.Maximum = 100000;
        progressBar1.Step = 1;

        for(int j = 0; j < 100000; j++)
        {
            Caluculate(j);
            progressBar1.PerformStep();
        }
    }
}

我应该在每次计算后执行步骤。但是如果我在外部方法中执行所有100000次计算呢?如果我不想让这个方法依赖于进度条,我应该什么时候“执行步骤”?例如,我可以写

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void CaluculateAll(System.Windows.Forms.ProgressBar progressBar)
    {
        progressBar.Maximum = 100000;
        progressBar.Step = 1;

        for(int j = 0; j < 100000; j++)
        {
            double pow = Math.Pow(j, j); //Calculation
            progressBar.PerformStep();
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        CaluculateAll(progressBar1);
    }
}

但我不想那样做。

共有3个答案

穆锋
2023-03-14

嘿,有一个关于点网珍珠的有用教程:http://www.dotnetperls.com/progressbar

在与彼得的协议中,您需要使用一些线程,否则程序就会挂起,有点违背目的。

使用ProgressBar和Background Worker的示例:C#

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, System.EventArgs e)
        {
            // Start the BackgroundWorker.
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 1; i <= 100; i++)
            {
                // Wait 100 milliseconds.
                Thread.Sleep(100);
                // Report progress.
                backgroundWorker1.ReportProgress(i);
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Change the value of the ProgressBar to the BackgroundWorker progress.
            progressBar1.Value = e.ProgressPercentage;
            // Set the text.
            this.Text = e.ProgressPercentage.ToString();
        }
    }
} //closing here
云卓
2023-03-14

自. NET 4.5以来,您可以使用async和wait与进步的组合来向UI线程发送更新:

private void Calculate(int i)
{
    double pow = Math.Pow(i, i);
}

public void DoWork(IProgress<int> progress)
{
    // This method is executed in the context of
    // another thread (different than the main UI thread),
    // so use only thread-safe code
    for (int j = 0; j < 100000; j++)
    {
        Calculate(j);

        // Use progress to notify UI thread that progress has
        // changed
        if (progress != null)
            progress.Report((j + 1) * 100 / 100000);
    }
}

private async void button1_Click(object sender, EventArgs e)
{
    progressBar1.Maximum = 100;
    progressBar1.Step = 1;

    var progress = new Progress<int>(v =>
    {
        // This lambda is executed in context of UI thread,
        // so it can safely update form controls
        progressBar1.Value = v;
    });

    // Run operation in another thread
    await Task.Run(() => DoWork(progress));

    // TODO: Do something after all calculations
}

任务是当前实现BackgroundWorker功能的首选方式。

这里更详细地解释了任务和进度

  • 4.5中的异步:在异步API中启用进度和取消
狄玉书
2023-03-14

我建议你看看Background Worker。如果你的WinForm中有一个这么大的循环,它会阻塞,你的应用程序看起来就像被挂起了一样。

查看Background Worker. ReportAdvanced(),了解如何将进度报告回UI线程。

例如:

private void Calculate(int i)
{
    double pow = Math.Pow(i, i);
}

private void button1_Click(object sender, EventArgs e)
{
    progressBar1.Maximum = 100;
    progressBar1.Step = 1;
    progressBar1.Value = 0;
    backgroundWorker.RunWorkerAsync();
}

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    var backgroundWorker = sender as BackgroundWorker;
    for (int j = 0; j < 100000; j++)
    {
        Calculate(j);
        backgroundWorker.ReportProgress((j * 100) / 100000);
    }
}

private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // TODO: do something with final calculation.
}
 类似资料:
  • null 但这三条不同的道路对我都不起作用。对于路径,以“无法找到指定的路径”失败。对于和路径,会出现“无法启动屏幕键盘”错误对话框。 我在这里找到了一个可能的解决办法,它比我想要的要复杂一点(二阳的帖子):http://social.msdn.microsoft.com/forums/en-us/netfx64bit/thread/10ebc62f-e6d7-4072-9fd1-ea3784a0

  • 我对Java没有太多的经验,并且很难得到一个进度条来工作。我正在使用NetBeans的内置GUI Maker。目前,我的程序从一个目录读取图像到一个图像数组。显然,这需要一点时间,因此我希望一个简单的进度条来更新用户,以了解加载的程度。我已经使用了其中一个拖放进度条组件。 我目前可以获取目录中的文件数,并可以计算加载文件的百分比 文件成功加载到数组中,但进度条只有在加载所有文件后才会更新。我尝试在

  • 本文向大家介绍如何使用纯html制作一个进度条?相关面试题,主要包含被问及如何使用纯html制作一个进度条?时的应答技巧和注意事项,需要的朋友参考一下 HTML中的progress () 元素用来显示一项任务的完成进度.虽然规范中没有规定该元素具体如何显示,浏览器开发商可以自己决定,但通常情况下,该元素都显示为一个进度条形式. 所有不建议在生产业务中使用 MDN链接

  • 问题内容: 我正在下载文件,但是对于大文件,我每次都需要检查磁盘上文件的大小,因为我无法以百分比形式显示进度,并且我也想知道下载速度。我该怎么做呢?这是我的代码: 我认为一种方法是在循环中每次读取文件并根据标头计算进度百分比。但是对于大文件(大约500MB),这将再次成为问题。还有其他方法吗? 问题答案: 参见此处:Python进度栏和下载 我认为代码将是这样,它应该显示 自开始以来 的 平均速度

  • 本文向大家介绍winforms 使用Visual Studio创建一个简单的WinForms应用程序,包括了winforms 使用Visual Studio创建一个简单的WinForms应用程序的使用技巧和注意事项,需要的朋友参考一下 示例 本示例将向您展示如何在Visual Studio中创建Windows Forms Application项目。 创建Windows窗体项目 启动Visual

  • 问题内容: 使用复制大型文件时,您没有任何指示操作进展的信息。 我已经把一些作品- 它使用一个简单的进度条类(简单的返回一个简单的ASCII进度栏,作为一个字符串),和一个环,并做实际的复制。它显示进度条,使用它有点黑,但它可以工作。 您可以在github上查看代码(在上下文中) 是否有任何内置模块可以更好地做到这一点?可以对此代码进行任何改进吗? 问题答案: 两件事情: 我想使默认的块大小, 很