如何仅从WPF MVVM中的调度程序线程以外的线程更新可观察集合中的属性? [英] How to update only a property in an observable collection from thread other than dispatcher thread in WPF MVVM?
问题描述
我有一个名为Employee
的class
.我只需要更新当前调度程序线程以外的线程的属性Status
:
I am having a class
named Employee
. I need to update only the property Status
from thread other than current dispatcher thread:
class Employee
{
public string Name { get; set; }
public string Status { get; set; }
}
Viewmodel(ViewModelBase
实现INotifyPropertyChanged
接口)
Viewmodel (ViewModelBase
implements INotifyPropertyChanged
interface):
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class DisplayViewModel : ViewModelBase
{
public static event EventHandler OnStatusChanged;
ObservableCollection<Employee> _dailyEmployees;
public ObservableCollection<Employee> DailyEmployees
{
get { return _dailyEmployees; }
set
{
_dailyEmployees = value;
OnPropertyChanged();
}
}
public DisplayViewModel()
{
OnStatusChanged += DisplayViewModel_OnStatusChanged;
}
//invoked in other thread
private void DisplayViewModel_OnStatusChanged(object sender, EventArgs e)
{
var d = sender as Employee;
if (d == null)
return;
var em = DailyEmployees.FirstOrDefault(a => a.Name == d.Name);
if(em == null)
{
DailyEmployees.Add(em);
}
else
{
em.Status = d.Status;
}
}
}
当我尝试向可观察的集合中添加值时,它会抛出
When i tried adding values to observable collection it throws exception as
这种类型的CollectionView不支持从与Dispatcher线程不同的线程对其SourceCollection进行更改"
"This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread"
我应该如何进行?谢谢.
How shall I proceed? Thanks.
推荐答案
可以使用分派器在UI线程上调用Add
方法:
Either use the dispatcher to call the Add
method on the UI thread:
Application.Current.Dispatcher.BeginInvoke(() => DailyEmployees.Add(em));
或在UI线程上调用 BindingOperations.EnableCollectionSynchronization 方法使集合可以在多个线程上使用:
Or call the BindingOperations.EnableCollectionSynchronization method on the UI thread to enable the collection to be used on multiple threads:
public class DisplayViewModel
{
private readonly ObservableCollection<Employee> _dailyEmployees = new ObservableCollection<Employee>();
private readonly object _lock = new object();
public ObservableCollection<Employee> DailyEmployees
{
get { return _dailyEmployees; }
}
public DisplayViewModel()
{
System.Windows.Data.BindingOperations.EnableCollectionSynchronization(_dailyEmployees, _lock);
OnStatusChanged += DisplayViewModel_OnStatusChanged;
}
//invoked in other thread
private void DisplayViewModel_OnStatusChanged(object sender, EventArgs e)
{
var d = sender as Employee;
if (d == null)
return;
var em = DailyEmployees.FirstOrDefault(a => a.Name == d.Name);
if (em == null)
{
DailyEmployees.Add(em);
}
else
{
em.Status = d.Status;
}
}
}
还请注意,如果希望设置该类的值反映在视图中,则Employee
类应实现INotifyPropertyChanged
接口并引发Status
属性的PropertyChanged
事件.
Also note that the Employee
class should implement the INotifyPropertyChanged
interface and raise the PropertyChanged
event for the Status
property if you want the value of this one to be reflected in the view when you set it.
这篇关于如何仅从WPF MVVM中的调度程序线程以外的线程更新可观察集合中的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!