MVVM:如何避免在列表场景的模型中使用 ObservableCollection?

MVVM: how to avoid using ObservableCollection in model in a list of lists scenario?

我有一个包含可编辑(添加、修改、删除)MyBaseListModel 项目列表的视图。 每个单独的 MyBaseListModel 项目本身都有一个成员子列表,可以使用扩展器打开该子列表以显示单独的模型项目。此列表也可以编辑。 可以同时打开两个不同的子列表。

首先,我直接在模型中实现了 ObservableCollections:

public class MyBaseListModel
{
    ObservableCollection<MyBaseModel> MyBaseList;
    // other members
}

然后是虚拟机:

public class MyViewModel
{
    public ObservableCollection MyListsfList;

    public MyViewModel(List<MyBaseListModel> l)
    {
        MyListofList = new ObservableCollection(l);
    }
    ....
 }

这工作正常。

然后我读到直接在模型中实现 ObservableCollections 不是一个好的习惯,我同意。 所以我将模型更改为使用列表:

public class MyBaseListModel
{
    List<MyBaseModel> MyBaseList;
    // other members
}

但是现在我无法编辑单个子列表,因为 MyListofList[i].MyBaseList 本身就是一个简单的列表,而不是一个 ObservableCollection。

我是否应该重建视图模型构造函数中的每个 MyBaseListModel 项以用 ObservableCollection 替换 List?

或者我应该在 VM 中构建 MyBaseList 上的 ObservableCollection 包装器集合吗?

或者我应该分层组合不同的 ViewModel,创建一个 MyBaseListViewModel,使用 ObservableCollection 包装每个 MyBaseListModel 对象?

谢谢。

ObservableCollection<T>List<T> 之间的主要区别是前者实现 INotifyCollectionChanged 接口并在添加或删除项目时向 UI 发出通知.如果你需要这个,你应该使用 ObservableCollection<T>。如果不这样做,您还不如使用 List<T>。两种类型都实现了 IList<T> 和 `ICollection' 接口,并且可以修改。

ObservableCollection<T> 添加到 MyBaseListModel 之类的 class 并没有错,前提是这是特定于客户端的类型。如果 MyBaseListModel 是在客户端和服务器端的不同项目之间共享的某种领域对象,您应该考虑将其包装在视图模型中,即 "child" 视图模型19=],在客户端而不是修改实际的域对象。

直接绑定到 WPF 应用程序中的域、业务或数据传输对象很少有用。创建 UI 特定包装器对象并绑定到这些对象通常是更好的方法,至少如果您出于某种原因不能按原样使用 "original" 对象。

ObservableCollection 有一个接受 IEnumerable 的构造函数,因此您只需传入您的列表即可。

不知道谁告诉你模型不应该有 ObservableCollection,但他们告诉你错了。事实上,EF 和 NHibernate 开箱即用地支持它。

更大的问题是,为什么您认为拥有一个不可观察的模型 v1 是个好主意,然后创建该模型 v2 的精确克隆只是为了使其可观察,然后必须在两者之间不断转换.

事实上,您不应该在 VM 中使用精确模型对象的唯一时间是它们需要重新打包/转换时。如果它们需要重新打包/转换,您可能应该重新考虑为什么不首先以这种方式构建它们。