获取MVVM Light中UserControl的当前ViewModel

时间:2016-08-04 12:09:24

标签: c# mvvm user-controls win-universal-app mvvm-light

我有一个UserControl,用于多个View。每个View都有自己的ViewModel。我知道我可以使用

从其代码中获取ViewModel的当前UserControl
GamePageViewModel viewModel = ServiceLocator.Current.GetInstance<GamePageViewModel>();

但是,由于UserControl可以根据其当前所在的ViewModel与任何View相关联,因此如何从ViewModel获取正确的UserControl代码背后?

3 个答案:

答案 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";
    }