【问题标题】:Winform utilizing progress bar and file copyingWinform 利用进度条和文件复制
【发布时间】:2015-07-17 12:01:23
【问题描述】:

我有一个带有发布按钮、取消按钮、标签和进度条的表单。当我单击该按钮时,复制到不同目录所需的所有文件都会被复制。这部分工作正常。我现在使用进度条让用户知道在任何给定时间正在发布什么文件。这样,如果出现问题或文件非常大,用户就会知道是什么文件导致了问题(通过标签)。这些文件通过字符串列表填充。最初,我只是使用 Thread.Sleep 使该过程比复制文件的瞬间更长。但是,仅使用它会阻止与 UI 的交互(例如,如果用户想要取消)。所以我正在使用 BackgroundWorker 来完成我的问题。

点击“发布”时我预计会发生什么

标签告诉我“开始发布...”。每个文件后,进度条值递增,标签指示正在发布的文件,当复制结束时,标签显示“发布完成”,进度条值最大化。

什么不会发生

标签不会为文件更新。它只是说“开始发布”然后“发布完成”。

问题

如何正确“报告进度”,以便在复制每个文件后更新我的标签?

代码

   private void btnPublish_Click(object sender, EventArgs e)
        {
            try
            {                
                ProgressBar();
            }
            catch (Exception ex)
            {

                Data.Common.ErrorHandling.DisplayError(ex);
            }
        }



private void ProgressBar()
        {
            lblPublish.Text = "Starting publication...";
            //DoWork
            if (!backgroundWorker1.IsBusy)
            {
                backgroundWorker1.RunWorkerAsync();
            }
        }




 private void btnCancel_Click(object sender, EventArgs e)
    {
        if (backgroundWorker1.IsBusy)
        {
            backgroundWorker1.CancelAsync();
        }
    }


  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            List<string> allAcros = NumOfTotalAcros();
        foreach (var acro in allAcros)
        {
            backgroundWorker1.ReportProgress(allAcros.IndexOf(acro));
            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true;
                backgroundWorker1.ReportProgress(0);
                return;
            }
            Thread.Sleep(500);
        }

    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        List<string> acros = new List<string>();
        cdsPublishBar.Value = e.ProgressPercentage;
        for (int i = 0; i < acros.Count; i++)
        {
            lblPublish.Text = "Processing " + acros[i].ToString() + "...";
        }
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            lblPublish.Text = "Processing cancelled";
        }
        else if (e.Error != null)
        {
            lblPublish.Text = e.Error.Message;
        }
        else
        {
            cdsPublishBar.Value = 100;
           lblPublish.Text = "Publish Complete";

        }
    }

【问题讨论】:

  • 您确定要在 _ProgressChanged 方法中使用 List&lt;string&gt; acros = new List&lt;string&gt;();。 List acros 的长度为 0,因此 for 循环没有迭代。
  • @WilliamMoore 在你发帖后我才注意到。我在别处正确地定义了它,但在那里没有。

标签: c# winforms backgroundworker


【解决方案1】:

您正在创建一个新的 empty 集合,该集合与 DoWork 事件中的集合无关,然后对其进行迭代...这将永远不会打印任何内容。

// empty list
List<string> acros = new List<string>();

// no elements to iterate over
for (int i = 0; i < acros.Count; i++)
{
    lblPublish.Text = "Processing " + acros[i].ToString() + "...";
}

相反,通过ReportProgress 的第二个参数传递您需要的值:

backgroundWorker1.ReportProgress(0, acro);

然后在ProgressChanged 方法中使用它:

cdsPublishBar.Value = e.ProgressPercentage;
lblPublish.Text = string.Format("Processing {0}...", e.UserState);

【讨论】:

  • 谢谢哥们。是的,我没有抓住空列表部分。另外,我没有添加的是将进度条最大值设置为列表的大小(而不是默认的 100),并在进度更改时将其递增 1(而不是 (e.ProgressPercentage)。
猜你喜欢
  • 2010-11-20
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 2016-06-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
相关资源
最近更新 更多