使用 INotifyPropertyChanged 和 Dispatcher 更新视图

本文关键字:更新 新视图 Dispatcher INotifyPropertyChanged 使用 | 更新日期: 2023-09-27 18:34:45

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

铌!这不是一个可观察集合,我读过调度程序不处理。

视图模型中的示例代码

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以防万一,但没有结果。我确实知道绑定可以将其设置为默认值,以及完成后进度条被填充的事实。

所以。。。我在这里做错了什么?还是我被误导了调度员能够处理这个问题?感觉这一定是很常见的场景。

使用 INotifyPropertyChanged 和 Dispatcher 更新视图

您可以使用 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);
            }
        });
    }