Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF MVVM在后台工作程序上更新视图模型_Wpf_Mvvm_Backgroundworker - Fatal编程技术网

WPF MVVM在后台工作程序上更新视图模型

WPF MVVM在后台工作程序上更新视图模型,wpf,mvvm,backgroundworker,Wpf,Mvvm,Backgroundworker,这封信有效吗 我想维护一个项目 我有一个视图模型,它将项对象(实现INotifyPropertyChanged)作为视图绑定到的属性公开 将Item对象传递给修改它的Backgroundworker,然后在BackgroundWorking完成时引发PropertyChanged事件对我来说有效吗 或者BackgroundWorker不应该以任何方式修改Item对象。我将使用BackgroundWorker传回的结果更新现有的Item对象。这将在RunWorkerCompleted事件中完成。但

这封信有效吗

我想维护一个项目

我有一个视图模型,它将项对象(实现INotifyPropertyChanged)作为视图绑定到的属性公开

将Item对象传递给修改它的Backgroundworker,然后在BackgroundWorking完成时引发PropertyChanged事件对我来说有效吗

或者BackgroundWorker不应该以任何方式修改Item对象。我将使用BackgroundWorker传回的结果更新现有的Item对象。这将在RunWorkerCompleted事件中完成。但是这是否会锁定UI线程并击败拥有backgound worker的目标

困惑

我会尽力解释的

用户可以选择创建项目。我创建视图和视图模型。在视图模型中,将创建一个空项对象。他被介绍来维护这个项目。在选择Item Type属性时,这会启动一个复杂的过程来创建用户要输入的项目列表。我可以在创建列表时阻止UI线程,但这会带来糟糕的用户体验。我希望将处理过程传递给后台线程,同时保持UI的活动状态。目前,我设置了一个标志来指示视图上的部分正在加载,将Item对象传递给BackgroundWorker,后者将更新可观察的属性集合。后台工作完成后,我调用PropertyChanged事件,该事件更新绑定到列表的视图部分,并关闭标志以指示该部分正在加载。这似乎没有任何问题。但是我有一种直觉,我不应该在后台线程中更新视图模型中的绑定对象


谢谢你,蒂姆。听起来不错。只要您的项目对象是
依赖对象
,您就可以在后台工作程序中更改它们的属性。
将数据绑定到对象的属性将起作用,绑定引擎将自动为您切换线程。
但是,不要在后台工作程序中填充数据绑定集合或操作DependencyObjects(如UI控件)的属性,而不分派操作。这将导致一个例外

编辑:
仅供澄清:真正的问题不是,如果项对象是
DependencyObject
,而是属性是
CLR属性
DependencyProperty
。因为DependencyProperties绑定到DependencyObjects,所以我经常使用上面的简化,但这并不是全部事实。

这意味着,如果您有CLR属性,则可以从外部线程设置其值,而不管您的类是否为
dependencyObject
。这与我的第一句话略有不同。

哇,超快速回复,谢谢。你能解释一下你所说的操纵是什么意思吗?@Tim:对不起,我的英语。我的意思是用UI线程的调度程序调用操作。调度程序将在右侧(UI)线程中调度操作的执行。谢谢,只要运行一个测试,我确实会得到一个错误。将调查。发现这篇文章似乎做的工作!分派意味着您必须在backgroundworker中编写类似的内容:Application.Current.Dispatcher.BeginInvoke(新操作(()=>…下面是您在ui线程中想要执行的操作…);