我一直关注mvvmlight
来编写项目代码。我有3个xaml
个文件MainWindow
,View1
,View2
,
我已在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
View2
是xmal
命名空间下的MyProject.View
个文件。
我正在尝试初始化MainViewModel
中的所有视图,因此我访问了MainViewModel
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
无法在此处访问,解决此问题的最佳方法是什么?
答案 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。