Reputation: 2765
I have been following the mvvmlight
to code a project. I have 3 xaml
files MainWindow
, View1
, View2
,
I have registered all three viewmodels in my ViewModelLocator
, as well as a data service used by 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());
}
}
The View1Model
requires a IView1Service
as constructor input,
public View1Model(IView1Service view1Service)
{
_view1_service = view1Service;
}
In my App.xaml
I have registered them as below
<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>
And of course View1
View2
are xmal
files under the MyProject.View
namespace.
I was trying to initialize all the views in my MainViewModel
, so I access all the viewmodel instances in 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());
in this line of code, I was hoping to get it from ViewModelLocator
instead of passing a View1Service
object. But the Locator
I registered in App.xaml
is not accessible here, what is the best to way to work around this problem?
Upvotes: 1
Views: 2965
Reputation: 815
I've using MVVMLight to developed for the Universal App, not WPF. But I guess it should be similar.
You don't have to explicitly create a new instance of the ViewModel. It is a Singleton, so a instance will be created when ServiceLocator.Current.GetInstance<T>()
is first called.
Also, SimpleIoc is smart enough to find a suitable class (match the type that register before, IView1Service
in this case) to instantiated if it needs a parameter.
The Locator
you registered in App.xaml is used in other xaml, like:
<Page
...
DataContext="{Binding View1, Source={StaticResource Locator}}"
>
To get the ViewModel instance in code, just like @goobering 's answer.
View1Model vm = (new ViewModelLocator()).View1;
It is safe to create many ViewModelLocator instances, and the ViewModel returned is the same object.
Upvotes: 3
Reputation: 1553
I do this by creating the ViewModelLocator as a private field in my ViewModel
public class MyViewModel : ViewModelBase
{
private ViewModelLocator _locator;
public MyViewModel()
{
_locator = new ViewModelLocator();
}
}
Then you can access your ViewModels through your ViewModelLocator using: _locator.View1
, _locator.View2
, etc.
Upvotes: 1