我对wpf和mvvm很新,所以这可能是一个简单的问题,但我希望有人可以向我解释。我的模型中有一个类,它只是轮询进程,如果它看到“calc”正在运行,它会将进程id添加到List中。如果关闭calc.exe,它会从List中删除它。如果列表更改它将触发和事件。在我的ViewModel中,我订阅了该事件并更新了触发PropertyChanged的属性。现在,如果我的属性是视图模型中的列表,那么我视图中的绑定不会正确更新。如果我在我的Model和ViewModel中将List更改为ObservableCollection,那么我会遇到一个跨线程问题。但是,如果我将我的List留在我的模型中并将我的ViewModel中的属性更改为ObservableCollection并将列表的值复制到一个可观察的集合中,一切都按预期工作....我不明白,我真的需要进行复制以使我的ListBox中的绑定正常工作吗?
答案 0 :(得分:0)
您需要从调度线程更新observable集合。
类似的东西(在技术上/语法上不正确,但是伪装近似)
Dispatcher.BeginInvoke( () => theList.Add( theThing ) );
答案 1 :(得分:0)
实现此功能的更好方法是通过ViewModel中的属性公开Model,并将ListBox绑定到Model.ObservableList。在向此列表中添加和删除项目时使用John的建议。这不需要您将列表中的值复制到observablecollection。
所以你的viewModel代码想要
public class ViewModel
{
public Model Model { get { return _model; } }
}
xaml中的绑定:
<ListBox ItemsSource=Model.ObservableList/>
其中ObservableList属性返回ObservableCollection。
由于WPF中的所有UI元素都具有线程关联性(对Dispatcher线程),因此应通过Dispatcher封送对UI的任何更新。您可以使用Dispatcher.Invoke通过Dispatcher封送调用。在这种情况下,您的view,viewModel和Model驻留在Dispatcher线程中,因此任何通过viewModel或Model更新UI的调用都需要您调用Dispatcher.Invoke。
答案 2 :(得分:0)
看看Cinch实现的DispatcherNotifiedObservableCollection。如果需要,它将自动使用Dispatcher。阅读本文以查看它的代码: