用于长时间运行功能的进度条WP7 C#

时间:2011-08-17 14:26:10

标签: c# windows-phone-7 user-interface progress-bar

我正在编写一个数独求解器应用程序。在某些情况下,求解器的计算时间可能超过3秒,这需要一个进度条。

所以我的代码:

private void solveButton_Click(object sender, RoutedEventArgs e)
{
    progressBar1.Visibility = Visibility.Visible;
    progressBar1.IsIndeterminate = true;
    mySolver.Solve(initialValue)
    progressBar1.Visilibity=Visilibity.collapsed;
    progressBar1.IsIndeterminate = false;
}

这里的代码是我实际代码的精简版本。此代码不起作用,因为进度条根本不显示。在我看来,UI只在事件执行完毕后才更新。如果我在解算器步骤之后没有隐藏进度条,则在数独解决之后会出现progressBar。用thread.sleep(1000)替换解算器也会导致相同的UI更新。

感谢您的帮助。

5 个答案:

答案 0 :(得分:4)

问题是你的UI线程之间没有空闲来显示进度条 您需要使用后台工作程序来解决问题,并且在主UI线程中您应该显示进度条

  private void solveButton_Click(object sender, RoutedEventArgs e)
    {
       BackgroundWorker bg = new BackgroundWorker();
       bg.DoWork += new DoWorkEventHandler(DoWork);
       bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
       bg.RunWorkerAsync(); 

       progressBar1.Visibility = Visibility.Visible;
       progressBar1.IsIndeterminate = true;         
    }

void DoWork(Object sender, DoWorkEventArgs args)
{
     mySolver.Solve(initialValue)
}

void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
{

    //  this method will be called once background worker has completed it's task
      progressBar1.Visilibity=Visilibity.collapsed;
      progressBar1.IsIndeterminate = false
}

答案 1 :(得分:4)

您应该在单独的线程上启动解算器。这样,即使在求解过程中,用户界面线程也可以继续处理用户界面对象,这样就可以在屏幕上绘制并更新进度条。

答案 2 :(得分:2)

从技术上讲,代码工作正常,你只是写错了代码。

您的求解程序正在UI线程上运行,因此在您再次隐藏它之前,它永远无法绘制进度条。您需要生成一个线程(或使用后台工作程序)来释放UI线程,以便它可以绘制您的进度条。

答案 3 :(得分:1)

我对WP7知之甚少,但如果你有一个长时间运行的函数需要winforms,它需要在与UI不同的线程上运行。

WP7上有BackgroundWorker可用吗?您可以更新ProgressChanged活动的栏,并更改RunWorkerCompleted活动的可行性

private void solveButton_Click(object sender, RoutedEventArgs e)
{
    progressBar1.Visibility = Visibility.Visible;
    progressBar1.IsIndeterminate = true;

    solveButton.Enabled = false; //I reccomend this so the button can't be pressed twice.

    BackgroundWoker bw = new BackgroundWorker();
    bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    bw.DoWork += bw_DoWork;
    bw.ProgressChanged += bw_ProgressChanged;
    bw.RunWorkerAsync()

}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    mySolver.Solve(initialValue, e)
}

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if(e.Error != null)
    {
         //Handle any exceptions that happened in the background worker.
    }
    progressBar1.Visilibity=Visilibity.collapsed;
    progressBar1.IsIndeterminate = false;
    solveButton.Enabled = true;
    ((IDisposable)sender).Dispose();
}

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

//inside mySolver
void Solve(somthing initialValue, DoWorkEventArgs e)
{
    //Your solver work
    e.ReportProgress(progress); //a int from 0-100
    //more solver work
}

答案 4 :(得分:0)

如果您仍想在UI线程上运行它(我不推荐!!),您可以使用昨天发布的WP7工具包中的进度条。它包含一个在您的UI线程被阻止时可以使用的进度条。