我有一个视图,其中包含MyBaseListModel项目的可编辑(添加,修改,删除)列表。 每个单独的MyBaseListModel项目都有自己的成员子列表,可以使用扩展器打开该成员子列表以显示各个模型项目。该列表也可以编辑。 可以同时选择两个不同的子列表。
首先,我直接在模型中实现了ObservableCollections:
public class MyBaseListModel
{
ObservableCollection<MyBaseModel> MyBaseList;
// other members
}
然后是VM:
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本身是一个简单的List,而不是ObservableCollection。
我应该重建视图模型构造函数中的每个MyBaseListModel项,以将List替换为ObservableCollection吗?
还是应该在VM上在MyBaseList上构建ObservableCollection包装器的集合?
还是我应该按层次结构组合不同的ViewModel,以创建一个MyBaseListViewModel来使用ObservableCollection封装每个MyBaseListModel对象?
谢谢。
答案 0 :(得分:1)
ObservableCollection<T>
和List<T>
之间的主要区别在于,前者实现INotifyCollectionChanged
界面,并在添加或删除项目时向UI发出通知。如果需要,请使用ObservableCollection<T>
。否则,您最好使用List<T>
。两种类型都实现IList<T>
和`ICollection'接口,并且可以修改。
向ObservableCollection<T>
之类的类添加MyBaseListModel
并没有错,只要这是特定于客户的类型。如果MyBaseListModel
是在客户端和服务器端的不同项目之间共享的某种域对象,则应考虑将其包装在视图模型中,即{{1}的“子”视图模型},而不是修改实际的域对象。
直接绑定到WPF应用程序中的域,业务或数据传输对象很少有用。通常,这是一种更好的方法,用于创建特定于UI的包装对象并绑定到这些包装对象,至少在由于某种原因而不能按原样使用“原始”对象的情况下。
答案 1 :(得分:1)
ObservableCollection具有一个接受IEnumerable的构造函数,因此您只需传递列表即可。
Dunno告诉您模型不应具有ObservableCollection,但他们确实告诉您错了。实际上,EF和NHibernate都提供了开箱即用的支持。
更大的问题是,为什么您认为拥有一个不可观察的Model v1,然后为该模型v2创建一个精确的克隆,只是为了使其可观察,然后必须继续在两者之间进行转换,是一个好主意。 / p>
实际上,唯一不应该在VM中使用EXACT模型对象的时间是当它们需要重新打包/转换时。而且,如果需要重新包装/转换它们,您可能应该重新考虑一下为什么一开始就没有采用这种方式来构建它们。