【发布时间】:2015-07-08 08:25:02
【问题描述】:
最近我开始深入研究 MVVM 来构建我正在开发的 WPF 应用程序。我正在努力了解如何在 Model 和 ViewModel 之间保持集合同步,以及如何验证用户将输入的信息。
假设我有一个(理论上的)类 Building,即模型,它将在运行时将建筑布局存储在内存中,否则通过序列化存储在 xml 中。 Building 有一个成员 List,并且该列表中的每个条目 Floor 都可以有其他 List,例如 List 和 List,它们又可以有 List 的成员(即 List)。
型号:
namespace TestMVVM
{
public class Building
{
public string strName { get; set; }
public List<Floor> floors { get; set; }
}
public class Floor
{
public int iNumber { get; set; }
public List<Room> rooms { get; set; }
}
public class Room
{
public int iSize { get; set; }
public string strName { get; set; }
public List<Door> doors { get; set; }
}
public class Door
{
public bool bIsLocked { get; set; }
}
}
在视图中,Floor 类型的列表可以在 DataGrid 中进行编辑。用户可以在 DataGrid 中输入新行以将 Floor 添加到 Building 类。在另一个 DataGrid 中,可以将房间添加到楼层。当我将所有列表都变成 ObservableCollections 并直接将它们与视图耦合时,这非常容易。但是,这也意味着没有适当的关注点分离,一旦验证开始就会变得混乱。
所以我写了一个 ViewModel 类,BuildingViewModel。它将保存对模型实例的引用。这就是我遇到麻烦的地方:ViewModel 将保存一个 FloorViewModel 类型的 ObservableCollection。但是当用户添加一个条目时,我如何在模型中的列表中也添加一个条目?大多数情况下,保持数据同步?如果将房间添加到楼层,或将门添加到房间怎么办,如何知道模型中的哪个位置更新哪些数据? IE。如何同步嵌套列表成员数据?
随后我会确保不会创建重复的楼层; IE。如果用户使用 List 中已有的数字添加楼层,则 DataGrid 必须报告错误。如果编辑现有楼层,则相同,房间名称也相同。我认为这种错误检查不能在 FloorViewModel 类中发生,因为它无法访问自身的其他实例。
我搜索了很多,但没有找到明确的答案。这似乎是一个相当普遍的情况?也许我只是走错了方向?
这是当前的 ViewModel,其中 ViewModelBase 是一个通用类,包含 INotifyProretyChanged 和 INotifyDataErrorInfo 的实现。
namespace TestMVVM
{
public class BuildingViewModel : ViewModelBase
{
private Building building;
public string strName
{
get { return building.strName; }
set
{
building.strName = value;
if (value == "") AddError("strName", "Name cannot be empty.");
OnPropertyChanged("strName");
}
}
public ObservableCollection<FloorViewModel> floors
{
// what goes here? how to sync members of floor to the model, and validate data?
}
public BuildingViewModel(Building b)
{
building = b;
}
}
public class FloorViewModel : ViewModelBase
{
public ObservableCollection<Room> rooms
{
// what goes here? how to sync members of room to the right Floor of the model, and validate data?
}
}
// etc
}
【问题讨论】: