MVVMLight ViewModelLocator创建新的ViewModel

时间:2015-04-29 06:40:03

标签: c# wpf xaml mvvm mvvm-light

我一直关注mvvmlight来编写项目代码。我有3个xaml个文件MainWindowView1View2

我已在ViewModelLocator注册了所有三个视图模型,以及View1Model使用的数据服务

    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        SimpleIoc.Default.Register<IView1Service, View1Service>();
        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<View1Model>();
        SimpleIoc.Default.Register<View2Model>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>(Guid.NewGuid().ToString());
        }
    }
    public View1Model View1
    {
        get
        {
            return ServiceLocator.Current.GetInstance<View1Model >(Guid.NewGuid().ToString());
        }
    }
    public View1Model View2
    {
        get
        {
            return ServiceLocator.Current.GetInstance<View2Model >(Guid.NewGuid().ToString());
        }
    }

View1Model需要IView1Service作为构造函数输入,

   public View1Model(IView1Service view1Service)
    {
        _view1_service = view1Service;
    }

在我的App.xaml我已将其注册如下

<Application.Resources>
    <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    <DataTemplate DataType="{x:Type vm:View1Model}">
          <views:view1 />
    </DataTemplate>
    <DataTemplate DataType="{x:Type vm:View2Model}">
          <views:View2 />
    </DataTemplate>
</Application.Resources>

当然View1 View2xmal命名空间下的MyProject.View个文件。

我正在尝试初始化MainViewModel中的所有视图,因此我访问了MainViewModel

中的所有viewmodel实例
    public MainViewModel()
    {
        // Add available pages
        PageViewModels.Add(new View1Model(new View1Service()));  // <========How to get this from the ViewModelLocator ?
        PageViewModels.Add(new View1Model());

        // Set starting page
        CurrentPageViewModel = PageViewModels[0];

    }
在这行代码中

PageViewModels.Add(new View1Model());,我希望从ViewModelLocator获取它而不是传递View1Service对象。但是我在Locator注册的App.xaml无法在此处访问,解决此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

我使用MVVMLight为Universal App开发,而不是WPF。但我想它应该是相似的。

您不必显式创建ViewModel的新实例。它是一个Singleton,因此在首次调用ServiceLocator.Current.GetInstance<T>()时将创建一个实例。

此外,SimpleIoc非常智能,可以找到一个合适的类(匹配之前注册的类型,在这种情况下为IView1Service),以便在需要参数时进行实例化。

您在App.xaml中注册的Locator用于其他xaml,例如:

<Page
...
DataContext="{Binding View1, Source={StaticResource Locator}}"
>

要在代码中获取ViewModel实例,就像@goobering的回答一样。

View1Model vm = (new ViewModelLocator()).View1;

创建许多ViewModelLocator实例是安全的,返回的ViewModel是同一个对象。

答案 1 :(得分:1)

我通过在ViewModel中将ViewModelLocator创建为私有字段来实现此目的

public class MyViewModel : ViewModelBase
{
    private ViewModelLocator _locator;

    public MyViewModel()
    {
        _locator = new ViewModelLocator();
    }
}

然后,您可以使用:_locator.View1_locator.View2等通过ViewModelLocator访问ViewModel。