在MVVM Light中获取UserControl的当前ViewModel
本文关键字:ViewModel UserControl 获取 MVVM Light | 更新日期: 2023-09-27 18:00:15
我有一个UserControl
,用于多个View
s。每个View
都有自己的ViewModel
。我知道我可以使用从UserControl
的代码后面获得ViewModel
的当前值
GamePageViewModel viewModel = ServiceLocator.Current.GetInstance<GamePageViewModel>();
但是,由于UserControl
可以根据其当前所在的View
与任何ViewModel
关联,我如何从后面的UserControl
代码中获得正确的ViewModel
?
只需在代码背后调用控件的DataContext。假设您有UserControl
类型的实例MyControl
,并且您想要它的ViewModel实例GamePageViewModel
类型的MyControlViewModel
。在这种情况下,您可以使用获得实例
GamePageViewModel MyControlViewModel = MyControl.DataContext as GamePageViewModel;
如果需要访问可与UserControl
一起使用的所有ViewModel的一些公共属性,请指定一个接口(或另一个基类)并将DataContext
强制转换为此接口。
但是,通常直接指定UserControl
的DataContext
是个坏主意。如果要将一些上下文传递到UserControl
中,请使用此处所述的依赖属性(请参阅Use dependency properties to pass parameters to a view
部分).
您可以简单地询问控件本身的DataContext。代码将搜索依赖关系树,直到找到数据上下文(应该是托管页面的ViewModel)。根据您设计ViewModel的方式,您可以用多种不同的方式处理它。这里有一些可能对你有用,或者可能需要你重新设计。
这些方法是由@Fruchtzberg和@mechtich提出的。我只是想澄清一下
似乎还有其他选项不涉及从代码后面询问视图模型,但没有说明代码的用途。
(正如你的帖子所建议的,所有代码都在后面的用户控制代码中)
一堆if/then语句(可能是最不受欢迎的)
if (DataContext is ViewModelA)
{
var _vm = (ViewModelA)DataContext;
_vm.DoViewModelAMethod();
_vm.Property1 = "abc";
}
else if (DataContext is ViewModelB)
{
var _vm = (ViewModelB)DataContext;
_vm.DoViewModelBMethod();
_vm.Property1 = "abc";
}
//etc. etc.
将通用方法/属性移动到基类(此处称为VMBase)并从中继承视图模型(以及VMBase从MVVMLight ViewModelBase继承?)
var _vm = DataContext as VMBase;
if(_vm != null)
{
_vm.DoViewModelMethod();
_vm.Property1 = "abc";
}
如果您使用的是通用方法/属性的不同实现,请使用和接口,并让视图模型实现接口。
var _vm = DataContext as IVMBase;
if(_vm != null)
{
_vm.DoViewModelMethod();
_vm.Property1 = "abc";
}