访问MVVM Light中其他ViewModel中的属性

时间:2013-06-04 08:29:19

标签: c# mvvm-light

我有一个主ViewModel,其中包含我在一定数量的UserControls中使用的项目列表,这些项目显示在主视图的ContentControl中。我目前在ViewModels之间交换数据的方式是在主要ViewModels中引用每个ViewModel,在每个{ViewModel中引用一个主UserControl 1}}。但是我不知道这是否是正确的方法,因为我有一个ViewModelLocator,我希望这个类有一些功能来支持这样的事情。

任何人都可以告诉我,如果我正在做这件事,或者在MVVM Light中有更好的方法吗?

编辑:

当我寻找不同的东西时,我发现了这个,这会是一个更好的解决方案吗?

private ViewModelLocator locator = new ViewModelLocator();

然后使用定位器属性来引用每个ViewModel?

EDIT2:

显然我认为会起作用的不是,起初我只在主ViewModel中有引用,但这很有效,但是当我在UserControls中尝试这种情况时,它会崩溃我的应用程序。我正在尝试第一次编辑的可能解决方案。

MainViewModel.cs(其他类似,仅参考主ViewModel)

public class MainViewModel : ViewModelBase
{
    private ItemAddViewModel itemAddViewModel;
    private ItemsViewModel itemsViewModel;

    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel()
    {
        ItemsList = Item.GetItemsList();

        itemAddViewModel = ServiceLocator.Current.GetInstance<ItemAddViewModel>();
        itemsViewModel = ServiceLocator.Current.GetInstance<ItemsViewModel>();

        ShowItemsView();
    }
...
    private void ShowItemsView()
    {
        CurrentControl = itemsViewModel;
    }
...

3 个答案:

答案 0 :(得分:17)

您实际上可以使用ViewModelLocator。默认情况下使用Inversion of Control Container,因此即使您创建了Locator的新实例,您也将从容器中获得相同的singleton viewmodels实例。

Locator类:

static ViewModelLocator()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    SimpleIoc.Default.Register<ViewModel1>();
    SimpleIoc.Default.Register<ViewModel2>();
    SimpleIoc.Default.Register<ViewModel3>();
}

public ViewModel1 ViewModel1
{
    get
    {
        return ServiceLocator.Current.GetInstance<ViewModel1>();
    }
}

public ViewModel2 ViewModel2
{
    get
    {
        return ServiceLocator.Current.GetInstance<ViewModel2>();
    }
}

public ViewModel3 ViewModel3
{
    get
    {
        return ServiceLocator.Current.GetInstance<ViewModel3>();
    }
}

然后从代码中可以访问它

var vm1 = (new ViewModelLocator ()).ViewModel1;

您获得了viewmodel的唯一实例。

来自xaml的

: 资源(默认位于App.xaml中的Application.Resources)

<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />

和视图的DataContext(用户控件或窗口或其他)

<UserControl
    ... 
    DataContext="{Binding ViewModel1, Source={StaticResource Locator}}"
    ...    >

答案 1 :(得分:1)

如果您只需要从主视图模型绑定属性,那么在内容控件中,只需使用以下语法:

   ... Binding="{DataContext.mainvmpropertyname, ElementName=xxxx}"

其中xxxx是附加到内容控件的名称(或将主视图模型作为其DataContext的任何控件)。或者,您可以使用相对绑定而不是元素名称。

答案 2 :(得分:1)

您可以通过从Apps资源获取定位器来以编程方式访问ViewModel定位器的公共属性:

MyViewModel vm = (App.Current.Resources["Locator"] as ViewModelLocator).MyViewModel

或在ViewModelLocator类中创建另一个静态实例:

public class ViewModelLocator
{
     public static ViewModelLocator Instance = new ViewModelLocator();

     static ViewModelLocator(){ ... }

     public MainViewModel Main
     {
     ...
     }
}

Similar Thread