使用 INotifyPropertyChanged 和 Dispatcher 更新视图
Using INotifyPropertyChanged and Dispatcher to update view
我试图让进度条根据循环执行的次数进行更新。循环在它自己的线程中是 运行。我的印象是 Dispatcher.BeginInvoke
是一个不错的选择并实施了它。我还读到调度程序能够更新 GUI,即使它是 运行 自己的线程。但是,在尝试通知绑定有关更新、实现 INotifyPropertyChanged
时,我无法使其正常工作。我看过一些博客、问题等建议使用不同的魔术方法来解决这个问题,但由于我已经读过这应该由调度员处理,所以我想避免这种情况。
注意!这是 不是 一个 Observable 集合,我读过它不是由调度程序处理的。
来自视图模型的示例代码
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
,但没有结果。我确实知道将绑定设置为默认值是可以的,而且完成后进度条会被填满。
所以...我在这里做错了什么?还是我被误导了调度员能够处理这个问题?感觉这应该是很常见的场景吧
您可以使用 Invoke 的通用实现,让另一个方法 returns "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);
}
});
}
我试图让进度条根据循环执行的次数进行更新。循环在它自己的线程中是 运行。我的印象是 Dispatcher.BeginInvoke
是一个不错的选择并实施了它。我还读到调度程序能够更新 GUI,即使它是 运行 自己的线程。但是,在尝试通知绑定有关更新、实现 INotifyPropertyChanged
时,我无法使其正常工作。我看过一些博客、问题等建议使用不同的魔术方法来解决这个问题,但由于我已经读过这应该由调度员处理,所以我想避免这种情况。
注意!这是 不是 一个 Observable 集合,我读过它不是由调度程序处理的。
来自视图模型的示例代码
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
,但没有结果。我确实知道将绑定设置为默认值是可以的,而且完成后进度条会被填满。
所以...我在这里做错了什么?还是我被误导了调度员能够处理这个问题?感觉这应该是很常见的场景吧
您可以使用 Invoke 的通用实现,让另一个方法 returns "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);
}
});
}