2011-03-04 64 views
6

这个senerio是否有效?WPF MVVM更新后台工作人员的视图模型

我有一个View来维护一个Item。

我有视图模型公开Item对象(实现INotifyPropertyChanged)作为视图被绑定到的属性。

对我来说,将Item对象传递给BackgroundWorker进行修改,然后在BackgroundWorking完成时引发PropertyChanged事件对我有效?

或者BackgroundWorker不应该修改Item对象。我会用BackgroundWorker传回的结果更新现有的Item对象。这将在RunWorkerCompleted事件中完成。但是,这是否锁定了UI线程并击败了具有backgound工作者的对象?

困惑?

我会尽力解释。

用户可以选择创建一个项目。我创建了视图和视图模型。在View模型中,创建一个空的Item对象。他会看到一个视图来维护该项目。在选择物品类型属性时,这会激发一个复杂的过程来创建用户输入的物品清单。我可以在创建列表时阻止UI线程,但这会给用户带来不好的体验。我想将处理传递给后台线程,同时保持UI活着。目前,我设置了一个标志来指示正在加载视图的部分,将Item对象传递给更新可观察属性集合的BackgroundWorker。当BackgroundWorking完成时,我调用PropertyChanged事件,该事件更新绑定到列表的View部分并关闭标志以指示部分正在加载。这似乎没有问题。但我有一种直觉,我不应该在后台线程中更新视图模型的绑定对象。

谢谢蒂姆

回答

8

这听起来没问题。只要您的项目对象是DependencyObject,您可以在后台工作中更改它们的属性。
DataBinding对象的属性将起作用,绑定引擎将自动为您执行线程切换。
但是,不要调度操作,不要在后台工作者中填充数据绑定集合或操作DependencyObjects(如UI控件)的属性。这会导致一个例外。

编辑:
只有澄清:真正的问题是没有,如果该项目对象为DependencyObject但如果该属性是CLR-propertyDependencyProperty。由于DependencyProperties绑定到DependencyObjects,我经常使用上面的简化,但它并不是完整的事实。
这意味着如果您有CLR属性,则可以从外部线程设置其值,而不管您的课程是否为DepenendencyObject。这与我第一次发言略有不同。

+0

WOW,超快速回复谢谢。你可以通过调度操作来解释你的意思吗? – Tim 2011-03-04 16:35:51

+0

@Tim:对不起,我的英语。我的意思是调用UI-Thread的调度程序的操作。调度员将在右侧(UI)线程中安排执行操作。 http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx – HCL 2011-03-04 16:44:19

+0

谢谢,只是运行测试,事实上我得到一个错误。将调查。 – Tim 2011-03-04 17:08:32