ViewModel是否保留模型?

时间:2011-04-01 11:37:09

标签: wpf mvvm

目前,我的应用程序结构如下:

  • 名为ViewModels的文件夹
  • 名为Views
  • 的文件夹
  • 名为Services
  • 的文件夹

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中。

这里有什么好方法?

2 个答案:

答案 0 :(得分:2)

(上面评论的第一部分:View应绑定到ViewModel .ViewModel无法了解潜在的视图。您可以编写一个新视图来使用现有的ViewModel - 或者您可以为ViewModel编写单元测试所以ViewModel中提到的视图是不合适的。)

我不确定你要做什么,但这看起来像是ItemType的详细视图。我不知道为什么你会在构造函数中查询所有项类型?

我会做这样的事情:

  • 创建ItemTypesViewModel,其集合为ItemTypeDetailViewModel,延迟加载
  • 在ViewModels用于查询模型(数据)的某个地方创建一个存储库(例如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