【问题标题】:In MVVM, should model objects be accessible by the view via a ObservableCollection<TModelObject> object? [closed]在 MVVM 中,视图是否可以通过 ObservableCollection<TModelObject> 对象访问模型对象? [关闭]
【发布时间】:2021-04-27 02:29:56
【问题描述】:

假设我有一个PersonModel 类对象的集合(显然位于我的应用模型中):

List<PersonModel> People { get;set; }

在我的应用视图中使用此对象的适当方式是什么,但作为ObservableCollection&lt;T&gt;

我是否需要在ViewModel 中创建一个PersonViewModel 类,然后将每个PersonModel 对象的内容复制到一个新的PersonViewModel 对象中,然后 插入每个将这些PersonViewModel 对象转换为ObservableCollection&lt;PersonViewModel&gt; 对象?

我之所以这么问,是因为到目前为止我的知识有限,视图甚至能够SNIFF一个模型对象似乎没有意义:

<ListView ItemsSource="{MY List<PersonModel> OBJECT}" />

这被认为是合适的吗?似乎 ListView 应该只知道 PersonViewModel 对象。谢谢!

【问题讨论】:

  • MVVM 是一种范式,而不是一套手铐。你是对的,模型对象(甚至视图模型对象)根本不应该知道视图对象。除此之外,关于 100% 的时间将模型对象包装在视图模型对象中的僵化,有赞成和反对的论点。当常规模型对象足够时,放弃视图模型对象是否合法,这是一个意见问题。

标签: c# wpf xaml


【解决方案1】:

MVVM 只是关注点分离。了解视图模型必须提供的内容是完全有效的——这是绑定的基础!所以利用这些绑定:

// Use of appropriate observable types - in collections
// ObservableCollection is the type you should use, as it notifies UI layers
// about collection changes. It implements INotifyPropertyChanged
ObservableCollection<PersonModel> People { get;set; }

如果您使用任何对象绑定到其属性,请通过实现INotifyPropertyChnaged 接口使其也“可观察”。所以你应该使用PersonViewModel,它应该实现所说的interafce(你可以把它想象成一个小的子视图模型)。

然后你就可以通过绑定在视图中使用它了:

<ListView ItemsSource="{Binding People}" />

备注

最好对集合使用只读字段并且只添加/删除项目,所以:

ObservableCollection<PersonModel> People { get; } = new ObservableCollection<PersonModel>();

【讨论】:

  • TC 立即写道,他的问题与集合类型无关。他自己理解 List 和 ObservableCollection 的区别。他的问题与这个集合的元素的实现有关:在什么情况下可以使用模型中的类型 (PersonModel),以及在什么情况下需要 ViewModel 级别的附加类型 (PersonViewModel)。
  • @EldHasp 我想我的编辑涵盖了所有方面:)
  • @MichałTurczyn 感谢您的回复。所以,如果 View 可以直接使用 ObservableCollection 对象,那么为什么这么多人会在 PersonViewModel 对象中大量包装 PersonModel 对象呢?因此,视图只能看到并绑定到 ObservableCollection 对象...
【解决方案2】:

这对解决的每个问题都非常具体。
一般来说,应用层之间交换不可变数据以避免寄生依赖。

在这种情况下,您的 PersonModel 类型将是不可变的。
如果在 Window 中只需要显示它而不能编辑(更改属性),那么使用 PersonModel 就足够了。
如果您需要 GUI 中的一些附加功能(新属性、可变性等),则必须创建一个附加类型。

而且不需要在PersonViewModel中重写来自PersonModel的所有值。 您可以简单地在 PersonViewModel 上创建一个属性来保存 PersonModel 实例。

使用 ObservableCollection 让视图“知道”集合已更改。
如果集合是动态的,即在其中实时移除/添加/替换元素,那么没有 ObservableCollection (INotifyCollectionChanged) 或 IBindingList 的绑定和 ItemsControl 的正确操作是无法实现的。
如果集合是静态的,并且总是只替换整个集合,或者在集合更改时设置一次,那么即使 List 也是多余的。 最好使用 IEnumerable 或 IEnumerable

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-24
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    相关资源
    最近更新 更多