【发布时间】:2011-12-29 00:42:35
【问题描述】:
是否可以同时使用声明性数据上下文和数据模板来连接视图和视图模型?
目标:我想在设计时将视图与一个 ViewModel 连接起来,而在运行时连接另一个 ViewModel。目前,对设计时 VM 使用声明性 DataContext 并在运行时使用 Data-Template 指定的 VM 的行为不符合预期。
背景 - 有多种方法可以连接 View 和 ViewModel,包括:
A.) 在 View 的 XAML 中以声明方式指定 ViewModel DataContext。这种技术在设计时使用无参数构造函数传入虚拟数据很有用。
<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 会使用方法 B 中指定的带有参数化构造函数的 ViewModel 版本覆盖方法 A 中指定的默认 DataContext。
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-first”场景中很有用,其中 ViewModel 被呈现,WPF 通过检查呈现的 ViewModel 的类型来解析和连接正确的 View。
问题 - 当将此方法 C 与方法 A 结合使用时,WPF 会解析正确的视图,但它似乎随后会重新查询视图,通过无参数构造函数调用以声明方式指定的视图模型(方法 A),从而覆盖现有的 ViewModel 属性!
问题 - 有没有一种方法可以同时使用这些技术(C 和 A)而不会让 A 无意中覆盖 C ViewModel 属性?
【问题讨论】:
-
如果您不希望声明发生,为什么要在 View 的 XAML 中以声明方式指定 ViewModel 的 DataContext?
-
我们的目标是找到一种在运行时同时支持设计时虚拟视图模型 (A) 和数据模板解析 (C) 的技术。
标签: .net wpf mvvm datacontext instantiation