2013-06-04 64 views
8

我有一个主要的ViewModel,其中包含我在一定数量的UserControls中使用的项目列表,这些项目显示在主视图上的ContentControl中。我目前在ViewModels之间交换数据的方式存在参考主要ViewModel中的ViewModels以及每个UserControl中的主要ViewModel中的一个。但是我不知道这是做这件事的正确方法,因为我有一个ViewModelLocator,我期望这个类有一些功能来支持这样的事情。在MVVM Light中访问其他视图模型中的属性

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

编辑:

我发现这个时候我正在寻找不同的东西,这会是一个更好的解决办法?

private ViewModelLocator locator = new ViewModelLocator(); 

然后使用locator属性来引用每个ViewModel?

EDIT2:

显然,我以为会工作不,起初我只在主ViewModel有引用和这个工作,但是当我尝试这在UserControls它那种崩溃我的应用程序。我目前正在尝试第一次编辑的可能解决方案。

MainViewModel.cs(其它都相同,仅参照主视图模型)

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; 
    } 
... 

回答

17

实际上,你可以使用ViewModelLocator。默认情况下是使用控制容器的反转,所以即使你创建了一个新的Locator实例,你也会从容器中获得同样的singleton视图模型实例。

定位器类:

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; 

你会得到一个和视图模型的唯一实例。

从XAML: 资源(defaultly是在App.xaml中Application.Resources)

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

,并为DataContext的意见(用户控件或窗口或其他)

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

是的,你说得对,我刚刚测试过它,它的工作原理应该如此,谢谢你的详细解决方案,非常感谢! :) – Kryptoxx

+0

我很高兴它帮助:)。你当然可以使用更复杂的IOC容器,它可以让你做更多的技巧,而不是单体视图模型和构造器依赖注入。简单的国际奥委会很简单... – eMko

1

如果所有您需要的是绑定来自主视图模型的属性,而在内容控件中,只需使用以下语法:

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

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

1

你可以编程从应用程序的资源获得定位器访问视图模型定位的公共属性:

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

相关问题