【问题标题】:Using ViewModels in ObservableCollections in Prism在 Prism 的 ObservableCollections 中使用 ViewModel
【发布时间】:2019-01-18 23:02:49
【问题描述】:

据我所知,使用绑定到列表视图的 ObservableCollection 的默认方式是将模型类作为元素 (ObservableCollection<MyModel>)。所以当一个列表视图元素被选中时,我们使用 NavigateAsync 并传递模型,然后 ViewModel 可以使用它来“填充自身”。 这种方法的问题在于,无法在列表视图中使用 ViewModel 属性进行绑定。

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

【问题讨论】:

  • 你的第一句话不是指... with view model classes.吗?直接绑定到模型很少是一个好主意。
  • @Haukinger 这意味着模型类元素。所以 ObservableCollection。我正在编辑它以进行澄清。

标签: c# xamarin mvvm xamarin.forms prism


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 但这意味着,我的模型具有仅在视图中需要的属性。这不是完全反对 MVVM 吗?视图模型不正是为此而生吗?
  • 是的,我的意思是你在视图模型中为视图创建了复合属性。
  • 是的,这就是在“简单”MVVM 中完成的方式。但是 Prism 使用 View first 导航,所以我必须为自己初始化 ViewModel(不是问题),并以最佳方式将此 ViewModel 用于我正在导航到的视图,当单击一行时。这就是在 Prism 中不起作用的地方。
【解决方案2】:

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

您是否需要 ObservableCollection<PickLineViewModel> 取决于更改可能发生的位置 - 在最初创建 PickLines 的服务/模型中或在 GUI 中或两者兼而有之。无论如何,您必须确保更改从一侧(视图模型集合)传播到另一侧(模型集合)。谷歌wrapping observable collection 作为初学者(提示:尽可能避免双向同步)。这些blog posts 很旧,但仍然相关,并且可以很好地阅读。 this answer 中描述了一个简单的包装。

【讨论】:

  • 对于“简单的 MVVM”,这是完全正确的。但问题是,这不是 Prism 的工作方式。 Prism 在集合中使用模型,当单击列表元素时,会创建一个新视图,ViewModelLocator 会找到并实例化 ViewModel 并将模型等参数传递给它。那么如何在考虑 Prism 的情况下实现 ViewModel 集合呢?
  • ViewModelLocator 完全是可选的。它使视图优先导航变得简单,但在视图模型优先导航中不使用它。当没有上下文(一个屏幕到另一个屏幕)时,您首先使用视图进行最高级别的导航,但在一个屏幕内,您的视图模型通过属性公开其他视图模型,并且框架获取关联的数据模板。
  • 好的,非常感谢@Haukinger。这已经对我有很大帮助了。但是,如果我在导航之前有 ViewModel 实例,我是否可以在导航时传递该实例,这样 Prism 就不会尝试找到我正在导航到的视图的 ViewModel,而是使用我已经拥有的实例?
  • 反之亦然。如果您已经拥有视图模型实例,您只需在公开该实例的属性上发布属性更改事件,绑定的内容控件将使用新的数据模板自动更新。
  • 啊,我没有正确解释。我并不是说如何在我的 PickList(ViewModel) 中使用 ViewModel。我的意思是,例如,如果我单击选择列表中的一行,应用程序将导航到相应的视图。如果我使用 NavigationService.NavigateAsync Prisms ViewModelLocator 将找到 PickLine 视图的 ViewModel 类,将其实例化,将其设置为 BindingContext 并显示视图。但是我如何告诉 Prism 不要搜索 ViewModel 并在导航时实例化它,而是导航到视图并使用我在 PickList ViewModel 的 ObservableCollection 中已有的 ViewModel?
猜你喜欢
  • 1970-01-01
  • 2017-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多