gpt4 book ai didi

c# - 如何仅从 WPF MVVM 中的调度程序线程以外的线程更新可观察集合中的属性?

转载 作者:太空宇宙 更新时间:2023-11-03 22:43:12 24 4
gpt4 key购买 nike

我有一个名为Employee。我只需要从当前调度程序线程以外的线程更新属性 Status:

class Employee
{
public string Name { get; set; }
public string Status { get; set; }
}

Viewmodel(ViewModelBase 实现了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;
}
}
}

当我尝试向可观察集合添加值时,它抛出异常

“这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程更改其 SourceCollection”

我该如何进行?谢谢。

最佳答案

要么使用调度器在 UI 线程上调用 Add 方法:

Application.Current.Dispatcher.BeginInvoke(() => DailyEmployees.Add(em)); 

或调用BindingOperations.EnableCollectionSynchronization UI 线程上的方法,使集合能够在多个线程上使用:

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 接口(interface)并为 Status 引发 PropertyChanged 事件属性,如果你希望这个的值在你设置它时反射(reflect)在 View 中。

关于c# - 如何仅从 WPF MVVM 中的调度程序线程以外的线程更新可观察集合中的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51258222/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com