使用INotifyPropertyChanged和Dispatcher更新视图

时间:2016-02-15 05:57:51

标签: c# wpf inotifypropertychanged dispatcher

我试图根据循环执行次数来进入更新进度条。循环在它自己的线程中运行。我认为Dispatcher.BeginInvoke是一个不错的选择并实施它的印象。我还读到,即使调度程序运行自己的线程,调度程序也能够更新GUI。但是,在尝试通知绑定有关更新时,我无法使其工作,实现INotifyPropertyChanged。我已经看过一些博客,问题等提出了不同的魔术方法来解决这个问题,但是自从我读过这个应该由调度员处理后我想避免这种情况。

NB!这是一个Observable集合,我读过的集合不会由调度员处理。

来自viewmodel的示例代码

Application.Current.Dispatcher.BeginInvoke(() =>
{
    this.Progress = 0;
    for (int i = 0; i < this.nrOfLoops; i++)
    {
        // implementation goes here ...
        if (i % 100 == 0) // Only update every 100 cycle 
        {
             this.Progress = (double)i / nrOfLoops * 100;
             this.NotifyPropertyChanged("Progress");
        }
    }
}, DispatcherPriority.Background);

XAML

<ProgressBar Value="{Binding Path=Progress}"/>

GUI不会持续更新,只有在完成所有操作后才会填充到100%。为了以防万一,我尝试过使用DispatcherPriority,但没有结果。我知道绑定是可以的,从设置为默认值,以及完成后填充进度条的事实。

那么......我在这里做错了什么?或者我是否因为调度员能够处理此问题而被误导?感觉这必定是一种非常常见的情况。

1 个答案:

答案 0 :(得分:1)

您可以使用Invoke的通用实现,让另一个返回“Task”的方法负责管理您的进度条。

Application.Current.Dispatcher.Invoke<Task>(UpdateBar, DispatcherPriority.Background);

这是方法:

private Task UpdateBar()
    {
        return Task.Factory.StartNew(() =>
        {
            this.Progress = 0;
            for (int i = 0; i < 100; i++)
            {
                this.Progress = (double)i;
                this.NotifyPropertyChanged("Progress");
                Thread.Sleep(30);
            }
        });
    }