Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.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
C# 在Prism中的ObservableCollections中使用ViewModels_C#_Xamarin_Mvvm_Xamarin.forms_Prism - Fatal编程技术网

C# 在Prism中的ObservableCollections中使用ViewModels

C# 在Prism中的ObservableCollections中使用ViewModels,c#,xamarin,mvvm,xamarin.forms,prism,C#,Xamarin,Mvvm,Xamarin.forms,Prism,据我所知,使用绑定到listview的ObservableCollection的默认方法是将模型类作为元素(ObservableCollection)。因此,当选择listview元素时,我们使用NavigateAsync并传递模型,然后ViewModel可以使用该模型“填充自身”。 这种方法的问题是,无法在listview中使用ViewModel属性进行绑定 例如: 我有一个视图、ViewModel和模型“PickList”,其中包含一组“PickLine”对象,每个对象都有一个视图、View

据我所知,使用绑定到listview的ObservableCollection的默认方法是将模型类作为元素(
ObservableCollection
)。因此,当选择listview元素时,我们使用NavigateAsync并传递模型,然后ViewModel可以使用该模型“填充自身”。 这种方法的问题是,无法在listview中使用ViewModel属性进行绑定

例如: 我有一个视图、ViewModel和模型“PickList”,其中包含一组“PickLine”对象,每个对象都有一个视图、ViewModel和模型本身。PickLine对象包含属性“PickedQuantity”和属性“OpenQuantity”。现在在我的PickList视图中,我不想将这两个绑定到单独的项目(例如,两个标签),但我希望有一个标签来显示这两个项目,例如“PickedQuantity/OpenQuantity”。我知道这个例子可以通过使用多重绑定或类似的方法来解决。但这不是全部的意义。
我的PickLine ViewModel已经有一个属性“QuantityString”,我想通过DataTemplate将它绑定到listview元素的标签上。但我该怎么做呢。甚至可能吗?

创建一个结合了其他两个属性的属性并绑定到该属性。例如:

公共字符串FullQuantity{get{return$“{PickedQuantity}/{OpenQuantity}”;}

然后在
PickedQuantity
OpenQuantity
的设置器中,您将需要调用已设置的任何
PropertyChanged
方法来通知绑定属性更改,并传入
FullQuantity
属性名称,以便在
PickedQuantity
OpenQuantity
更改时更新绑定到
FullQuantity
的元素

这样,您只需将一个标签的文本绑定到一个特性,当两个数量特性中的任何一个发生更改时,该标签将得到更新


注意:我不熟悉Prism,但无论使用何种Mvvm框架,这种方法都应该有效

您的
PickListViewModel
应该公开一个集合属性,其项的类型为
PickLineViewModel
(而不是
PickLine


您是否需要一个
observedcollection
取决于可能发生更改的位置-在最初创建
PickLine
s的服务/模型中,或在GUI中,或两者中。无论如何,您必须确保更改从一侧(视图模型集合)传播到另一侧(模型集合)。谷歌
将可观察到的集合包装成一个开端(提示:如果可能,避免双向同步)。这些都很古老,但仍然相关,值得一读。中描述了一个简单的包装。

您的意思是
。。。查看模型类。
在您的第一句话中?直接绑定到模型很少是一个好主意。@Haukinger它的意思是使用模型类元素。可见的收集。我编辑它是为了澄清,但这意味着,我的模型有一个属性,它只在视图中需要。这不是完全反对MVVM吗?视图模型不正是为了这个吗?是的,我的意思是在视图模型中为视图创建复合属性。是的,在“简单”MVVM中就是这样做的。但是Prism使用视图优先导航,因此我必须为自己初始化ViewModel(这不是一个问题),并以最佳方式在单击一行时将此ViewModel用于导航到的视图。这是在Prism中无法实现的。对于“简单MVVM”,这是完全正确的。但问题是,这不是Prism的工作方式。Prism在集合中使用模型,当单击列表元素时,将创建一个新视图,ViewModelLocator将查找并实例化ViewModel,并将类似模型的参数传递给它。那么,如何在考虑Prism的情况下实现ViewModel集合呢?
ViewModelLocator
完全是可选的。它使视图优先导航变得简单,但在视图模型优先导航中不使用它。在没有上下文(一个屏幕到另一个屏幕)的情况下,您可以使用view first进行最高级的导航,但是在一个屏幕中,您的视图模型通过属性公开其他视图模型,框架获取相关的数据模板。好的,非常感谢,@Haukinger。这已经帮了我很多忙了。但是,如果在导航之前我有ViewModel实例,我是否可以在导航时传递该实例,这样Prism就不会尝试将ViewModel查找到我导航到的视图,而是使用我已经拥有的实例?它会反过来工作。如果您已经拥有视图模型实例,您只需在公开该实例的属性上发布属性更改事件,绑定的内容控件将自动使用新的数据模板更新。啊,我没有正确解释。我不是指如何在我的选择列表(ViewModel)中使用ViewModel。我的意思是,例如,如果我单击拾取列表中的一行,应用程序将导航到相应的视图。如果我使用NavigationService.NavigateAsync Prisms ViewModelLocator,它将找到PickLine视图的ViewModel类,将其实例化,将其设置为BindingContext并显示视图。但是,我如何告诉Prism不要搜索ViewModel并在导航时实例化它,而是导航到视图并使用我在PickList ViewModel的ObservableCollection中已有的ViewModel?