【问题标题】:WPF ProgressBar - make the progress bar completed after the operation finishedWPF ProgressBar - 使进度条在操作完成后完成
【发布时间】:2011-07-27 01:33:21
【问题描述】:

我有一个 WPF 表单,它运行带有进度条的后台操作。但问题是;

操作完成后,进度条仍在运行。我的意思是它表明操作正在进行中。

我怎样才能阻止它?这是我的全部代码;

System.ComponentModel.BackgroundWorker mWorker;

private void button1_Click(object sender, RoutedEventArgs e) {

    mWorker = new System.ComponentModel.BackgroundWorker();
    mWorker.DoWork +=new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
    mWorker.ProgressChanged +=new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
    mWorker.WorkerReportsProgress = true;
    mWorker.WorkerSupportsCancellation = true;
    mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    mWorker.RunWorkerAsync();

    while (pbProcessing.Value != 100) {

        if (!mWorker.CancellationPending) {

            try {

                pbProcessing.Value = (pbProcessing.Value + 0.01) % 100;

            } catch (System.Exception ex) {

                // No action required
            }

        } else {

            MessageBox.Show(this, "Process cancelled", "Cancel Process", MessageBoxButton.OK);
            break;

        }

        System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
               new System.Threading.ThreadStart(delegate { }));

    }

}

private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {

    // Do your work here, its on seperate thread
    System.Threading.Thread.Sleep(10000);

}
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {

    pbProcessing.Value = e.ProgressPercentage;

}
private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {

    // Stop Progressbar updatation  
    Window1 w = new Window1();
    w.Browser.Navigate(new Uri("http://stackoverflow.com"));
    w.Show();

}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {

    if (mWorker != null) {

        if (mWorker.IsBusy) {
            mWorker.CancelAsync();
        }

    }

}

【问题讨论】:

  • 什么意思它还在运行?不是100%吗?

标签: c# wpf progress-bar backgroundworker system.diagnostics


【解决方案1】:

如果要在工作完成后隐藏进度条,请将其Visibility 属性设置为Visibility.Hidden。如果您只想将其重置为初始状态,请将其设置为 Value0(或 pbProgressing.Minimum,如果您将其更改为默认值)。


附带说明,您的代码实际上没有意义:与其在按钮事件处理程序中不断更改pbProcessing.Value(这完全没用,因为在按钮事件处理程序完成之前不会执行任何 UI 更新),您应该只更改ProgressChanged 中的值。即,您的代码应如下所示:

System.ComponentModel.BackgroundWorker mWorker;

private void button1_Click(object sender, RoutedEventArgs e) {

    mWorker = new System.ComponentModel.BackgroundWorker();
    mWorker.DoWork +=new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
    mWorker.ProgressChanged +=new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
    mWorker.WorkerReportsProgress = true;
    mWorker.WorkerSupportsCancellation = true;
    mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    mWorker.RunWorkerAsync();

    // Don't do anything else here

}

private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
    for (int i = 1; i < 100; i++) {
        mWorker.ReportProgress(i);

        // Do some part of the work
        System.Threading.Thread.Sleep(100);

        // Check if the user wants to abort
        if (mWorker.CancellationPending) {
            e.Cancel = true;
            return;
        }
    }

    mWorker.ReportProgress(100);  // Done
}

private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) {
    pbProcessing.Value = e.ProgressPercentage;
}

private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) {

    // Stop Progressbar updatation  
    Window1 w = new Window1();
    w.Browser.Navigate(new Uri("http://stackoverflow.com"));
    w.Show();

    // Check the result
    if (e.Cancelled) {
        // show the message box that the task has been canceled
    }

    // Reset Progress bar
    pbProcessing.Value = 0;
}

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
    if (mWorker != null) {
        if (mWorker.IsBusy) {
            mWorker.CancelAsync();
        }
    }
}

【讨论】:

  • @heinzi 感谢您的回复。进度完成后,我一直在设置值 100 :) 感谢您的提示。
  • 另外,我想问一下进度条不是全部与进程同步的。我怎样才能让它与进度同步。
  • @heinzi 它应该是 e.Cancelled 在 worker_RunWorkerCompleted 方法中我猜。
  • @heinzi 是的,现在一切都同步了。它会有点偏离主题,但一开始,它显示的进展有点晚。当流程开始时,我们如何才能开始呢。
  • @tugberk_ugurlu_:是的,你是对的,它应该是 e.Cancelled。 “有点晚”可能是因为 Thread.Sleep 在进度条的任何更新之前完成。我已经用循环和更短的睡眠时间代替了它,所以它现在应该更具反应性。请记住,您需要将 Thread.Sleep 替换为实际执行一些有用工作的代码。 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多