目前,我的应用程序结构如下:
ViewModel有一个名为ItemTypeDetailViewModel的类。看起来如何:
public class ItemTypeDetailViewModel
{
private IItemTypenService itemTypeService;
public ObservableCollection<Models.ItemType> ItemTypes { get; set; }
public ICollectionView CollectionView { get; set; }
public ItemTypeDetailViewModel()
{
itemTypeService = new ItemTypeService();
itemTypeService.GetItemTypes();
CollectionView = CollectionViewSource.GetDefaultView(ItemTypes);
}
}
在类中我引用了服务层(现在没有DI,只是在构造函数中新建)。在itemTypeService的帮助下,我将获得ItemTypes的集合。这可能是更多的MVP结构?
但是现在我开始感到困惑,因为我看到MVVM的大部分示例都将模型包装在ViewModel中。
这里有什么好方法?
答案 0 :(得分:2)
(上面评论的第一部分:View应绑定到ViewModel .ViewModel无法了解潜在的视图。您可以编写一个新视图来使用现有的ViewModel - 或者您可以为ViewModel编写单元测试所以ViewModel中提到的视图是不合适的。)
我不确定你要做什么,但这看起来像是ItemType的详细视图。我不知道为什么你会在构造函数中查询所有项类型?
我会做这样的事情:
ItemTypesViewModel
,其集合为ItemTypeDetailViewModel
,延迟加载IItemTypeService
这样做我想象)一个简单的例子,没有延迟加载:
public class ItemTypesViewModel : ViewModelBase
{
private List<ItemTypeDetailViewModel> itemTypeViewModels;
public IEnumerable<ItemTypeDetailViewModel> ItemTypes
{
get
{
return itemTypeViewModels;
}
}
public ItemTypesViewModel(IItemTypeService service)
{
// populate itemTypeViewModels using service here
}
}
更新,更相关我认为/希望:我在访问服务层时通常做的是在ViewModel类中有一个静态成员作为工厂内存。例如:
public class ItemTypesViewModel : ViewModelBase
{
public static ItemTypesViewModel Create(IItemTypeService service)
{
// build and return object here
}
}
在某些时候你必须跨越界限,这种方法符合我个人的口味......有兴趣看看其他人做了什么。也许是ViewModels的一个额外的一层或一组工厂。 ?
答案 1 :(得分:2)
但现在我开始感到困惑 因为我看到的大多数例子 MVVM将模型包装在一个 视图模型。
这里有什么好方法?
如果您的每个数据项(模型)都很简单,并且您在View中使用它们的方式也很简单,那么从ViewModel“按原样”公开它们就没有任何问题(创建额外的工作)只因为从来不是一个好主意)。另一方面,如果您发现需要的功能并不是非常容易实现,则可能表明您需要将每个模型包装在自己的ViewModel中(ItemTypeViewModel
)。
您可能不需要ViewModel的示例是将项目显示在只读列表中,在这种情况下,您最好使用DataTemplate
而不再需要。反例如果你需要编辑它们并且需要验证编辑;然后,ViewModel将保存验证逻辑。
总结一下:如果没有理由,不要对MVVM狂暴。务实。
有关ViewModel有权访问View的最终说明:
只要你不使用视图的运行时类型的公共接口就没有问题。实际上,ViewModel-first MVVM 需要那个ViewModel有一个参考视图。许多人会告诉你这是一个自动错误 - 他们错了,并且可能受到View-first(大多数示例中发现的MVVM风格)没有ViewModel引用View。
如果View可以将ViewModel引用为DataContext
,那么反转也可以。重要的一点是如何使用该引用:public object View { get; set; }
当然很好因为它没有引入任何耦合;但public MyUserControl View { get; set; }
不是,因为它将ViewModel耦合到特定类型MyUserControl
。