在数据显示之前,忙碌指示器不会显示

时间:2015-05-18 21:06:18

标签: wpf mvvm

我的项目中有一个控件,它提供一个忙碌的指示器(旋转圆圈)。我希望它在用户选择文件以将数据加载到数据网格时运行。繁忙的指示器在我的数据网格填充之前不会显示。如何在检索数据时显示忙碌指示器?我相信我应该使用一个帖子,但我对它们并不太了解并且我正在努力学习。我尝试了很多不同的方法,下面是我的最新尝试,我不知道我是否在附近。

public void DoWork()
{
this.StartProgressBar();

Task.Factory.StartNew(() =>
    {
        UIDispatcher.Current.BeginInvoke(() =>
            {
                if (fileCompleted != null && !string.IsNullOrEmpty(fileCompleted.SelectedFile))
                {
                    this.TestResults.Clear();

                    LoadedFileInfo info = this.Model.OpenTestCompleted(fileCompleted.SelectedFile);

                    foreach (var model in info.Sequence.Models)
                    {
                        foreach (var details in model.Tests)
                        {
                            this.TestResults.Add(new TestResultsModel(details, model.Name.Substring(0, model.Name.IndexOf('.'))));
                        }
                    }
                }
            });
    });
}

private void StartProgressBar()
{
    TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();

    CancellationToken cancelationToken = new CancellationToken();
    Task.Factory.StartNew(() => this.StopProgressBar()).ContinueWith(
        m => 
        {
            this.ToggleProgressBar = true;
        },
        cancelationToken,
        TaskContinuationOptions.None, 
        scheduler);
}

private void StopProgressBar()
{
    this.ToggleProgressBar = false;
}

1 个答案:

答案 0 :(得分:3)

我真的同意@Ben,你应该研究如何使用任务。您正在创建后台线程,并在其中的UI线程上工作,这不可避免地持有UI线程。尝试更简单的东西,看看它是否有效。至于你的取消令牌,我不知道你是如何重置它的,因为它不是你班上的财产,所以这里有一个没有它的样本..

这样的事情怎么样:

public void DoWork()
{
   //done on the UI thread
   this.ToggleProgressBar = true;

  //done on the background thread, releasing UI, hence should show the progress bar
  Task.Factory.StartNew(() =>
  {
      if (fileCompleted != null && !string.IsNullOrEmpty(fileCompleted.SelectedFile))
      {
          this.TestResults.Clear();
          LoadedFileInfo info = this.Model.OpenTestCompleted(fileCompleted.SelectedFile);

          foreach (var model in info.Sequence.Models)              
              foreach (var details in model.Tests)                  
                   this.TestResults.Add(new TestResultsModel(details, model.Name.Substring(0, model.Name.IndexOf('.'))));
       }
      //after all that (assumingly heavy work is done on the background thread,
      //use UI thread to notify UI
      UIDispatcher.Current.BeginInvoke(() =>
          {
             this.ToggleProgresBar = false;
          }
});

}