使用声明式DataContext为运行时设计时间和数据模板连接MVVM视图和ViewModel?

时间:2011-11-14 21:30:33

标签: .net wpf mvvm datacontext instantiation

是否可以使用Declarative DataContext和Data Template连接View和ViewModel?

目标:我想在设计时使用一个ViewModel连接视图,在运行时连接另一个ViewModel。目前,对于设计时VM使用Declarative DataContext,为运行时使用Data-Template指定的VM并不像预期的那样运行。

背景 - 有多种方法可以连接View和ViewModel,包括以下内容:

A。) 以声明方式指定View的XAML 中的ViewModel DataContext。这种技术在Design-Time中非常有用,它使用无参数构造函数传递虚拟数据。

<UserControl.DataContext>
    <my: BrowseAssetsViewModel />
</UserControl.DataContext>

B。) 以编程方式指定ViewModel,View和DataContext

// …Setup code
BrowseAssetsViewModel viewModel = new BrowseAssetsViewModel(assetRegistry, domains);
BrowseAssetsView view = new BrowseAssetsView();
view.DataContext = viewModel;

当方法B与方法A结合使用时,在运行时WPF会使用ViewModel的版本覆盖方法A中指定的默认DataContext,并使用方法B中指定的参数化构造函数。

C。)为View-ViewModel关联定义数据模板 通过在App.XAML Application.Resources中关联View和ViewModel,WPF可以根据ViewModel的类型连接正确的View。

<DataTemplate DataType="{x:Type vm: BrowseAssetsViewModel }">
    <vw: BrowseAssetsView />
</DataTemplate>

如果ViewModel属性绑定到ContentPresenter控件,WPF将连接相应的View(基于ViewModel的类型)并将其放在ContentPresenter中。这在ViewModel呈现的“ViewModel-first”场景中非常有用,WPF通过检查呈现的ViewModel类型来解析并连接正确的View。

问题 - 将此方法C与方法A结合使用时,WPF会解析正确的视图,但它似乎会重新查询View,通过无参数构造函数调用声明性指定的ViewModel (方法A),从而覆盖现有的ViewModel属性!

问题 - 有没有办法在没有A无意中覆盖C ViewModel属性的情况下一起使用这些技术(C和A)?

1 个答案:

答案 0 :(得分:8)

您可以指定DataContext以防止A仅在设计时设置,如下所示:

<UserControl ...
    d:DataContext="{d:DesignInstance my:BrowseAssetsViewModel}"
>

有关详细信息,请参阅MSDN上的Using a DesignInstance...