关于ViewModel管理的问题(DesignTime与运行时间)

时间:2011-07-14 15:55:22

标签: c# wpf xaml mvvm

我有一个相当基本的WPF UI,用户请求会导致我的TabControl中打开一个新选项卡。 TabControl绑定到ObservableCollection<ViewModelBase>

我将ViewModel实例添加到此集合中,并根据以下模板显示相应选项卡的内容:

    <DataTemplate DataType="{x:Type viewModels:UserUploadsViewModel}">
        <userControls:UserUploads />
    </DataTemplate>

现在让我们说在UserUploads控件内部,我想在XAML中连接一个ViewModel以帮助设计,如下所示:

<UserControl x:Class=".....UserUploads"
   .....
    DataContext="{Binding Source={StaticResource ViewModelLocater},
                  Path=UserAdministrationViewModel}">

此属性将在运行时返回带有实时服务的ViewModel,并在设计时返回带有模拟数据的ViewModel。

问题:这个XAML会干扰我在将TabItems内容绑定到ViewModel实例时所做的事情,并依赖上面的dataTemplate来呈现正确的View吗?如果是这样,有没有办法让这两个概念一起工作?

3 个答案:

答案 0 :(得分:23)

有一种更简单的方法可以做到这一点。有DesignTimeUserAdministrationViewModel并在构造函数中使用静态数据填充它,并在UserControl中将其引用为:

<UserControl d:DataContext="{d:DesignInstance designTimeVMs:DesignTimeUserAdministrationViewModel, IsDesignTimeCreatable=True}">

这样,您将设计时测试数据绑定到d:DataContext,并将运行时实时数据绑定到实际DataContext。更多详情here

答案 1 :(得分:1)

是的我认为它会干扰您当前的设置

ViewModelLocator是一个静态类,它在设计时返回一个虚拟对象,在运行时返回一个静态ViewModel。这意味着

  • ViewModelLocator,而不是您的ParentViewModel,包含您的TabViewModels

  • 您不能同时打开同一个标签(ViewModel)的多个实例

  • 除非您引用UserControl,否则您无法管理打开/关闭标签,这违反了MVM原则,其中ViewModel不知道视图

  • 您无法使用参数化构造函数实例化TabViewModel的新副本。例如,OpenTabs.Add(new CustomerViewModel(CustomerId));

也许替代品可能是转换器?一个在设计时返回静态对象,还是在运行时返回绑定对象?我从未测试过这样的东西,但理论上它应该可以工作:)

答案 2 :(得分:1)

内置的MS东西也不错,但是我正忙于在我的项目中加入的另一个更优雅,结构合理的替代方案是: http://msdn.microsoft.com/en-us/magazine/dn169081.aspx

基本上,您将MVVM Light工具包与其附带的SimpleIoc容器一起使用,最终能够为以下三种方案提供数据:

设计时间,运行时间和测试时间。

更好的是,MVVM Light的重点是让你的东西可以在Blend中直接编辑,并且有一系列的视频和博客以及描述它的示例应用程序。我希望我早些时候在我的WPF探索中找到了这些。