我有一个UserControl
,用于多个View
。每个View
都有自己的ViewModel
。我知道我可以使用
ViewModel
的当前UserControl
GamePageViewModel viewModel = ServiceLocator.Current.GetInstance<GamePageViewModel>();
但是,由于UserControl
可以根据其当前所在的ViewModel
与任何View
相关联,因此如何从ViewModel
获取正确的UserControl
代码背后?
答案 0 :(得分:1)
只需在后面的代码中调用控件的DataContext即可。假设您拥有类型为MyControl
的实例UserControl
,并且您希望它是MyControlViewModel
类型的ViewModel实例GamePageViewModel
。在这种情况下,您可以使用
GamePageViewModel MyControlViewModel = MyControl.DataContext as GamePageViewModel;
答案 1 :(得分:0)
如果您需要访问可以与UserControl
一起使用的所有ViewModel的公共属性,请指定一个接口(或另一个基类)并将DataContext
强制转换为此接口。
但是,通常直接指定UserControl
&#39; DataContext
是一个坏主意。如果要将一些上下文传递到UserControl
,请使用描述为here的依赖项属性(请参阅Use dependency properties to pass parameters to a view
部分)
答案 2 :(得分:0)
您可以简单地询问控件本身的DataContext。代码将搜索依赖关系树,直到找到数据上下文(应该是托管页面的ViewModel)。根据您设计ViewModel的方式,您可以通过多种不同的方式处理它。以下是一些可能对您有用的,或者可能需要您进行一些重新设计。
这些方法由@Fruchtzwerg和@mechanic提出。我只是想帮助澄清。
似乎还有其他选项不涉及从后面的代码中查询视图模型,但是没有说明代码的用途。
(所有代码都在用户控件代码隐藏中,正如您的帖子所暗示的那样)
一堆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";
}
如果您使用公共方法/属性的不同实现,请使用和接口并让viewmodel实现接口。
var _vm = DataContext as IVMBase;
if(_vm != null)
{
_vm.DoViewModelMethod();
_vm.Property1 = "abc";
}