My WPF application follows the MVVM pattern. There are three views:
LoginView
and ProjectsView
are user controls imported by the MainWindow
. Both views have their view model assigned. LoginViewModel
defines a property ProjectList
which is set by calling a webservice. Now LoginViewModel
needs access to the ProjectList
property and others.
I am aware that one solution might be a redesign so that there is only one view and one view model. I would do that as a backup solution but I would favor not to do so.
How should this be done? Should I use some kind of EventAggregator like in Prism? Or are there other ways to do this?
So if i understood clearly, ProjectList
property should be accessed from both 'LoginViewModel' and 'ProjectsViewModel'. I'd try to implement it in the 'MainViewModel' so child viewmodels can access it in a natural way.
An IEventAggregator is like a box in which you can add events, or find and subscribe to one, so i would say it's not what you need.
Anyway, you could register your custom interface (box type) in the UnitySingleton.Container
, which would expose ProjectList
for it to be accessible everywhere. This approach makes a lot of sense when modules, which are separate assemblies, need to communicate whith each other.
If this is overkill or not in your case is something you should decide, i'd personally go with the 'put it in the mainviewmodel' option.
-- Sample -- (not tested)
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
LoginVM = new LoginViewModel(this);
ProjectsVM = new ProjectsViewModel(this);
RetrieveProjectList();
}
public LoginViewModel LoginVM { get; private set; }
public ProjectsViewModel ProjectsVM { get; private set; }
public object ProjectList { get; private set; }
private void RetrieveProjectList()
{
ProjectList = ....
}
}
It's pretty simple as you see, LoginVM
and ProjectsVM
will hold a reference to the MainViewModel
that created them, therefore giving them access to ProjectList
.
How should this be done? Should I use some kind of EventAggregator
like in Prism? Or are there other ways to do this?
Here are a few ideas:
- You can create a view-model class that both view-models
inherit from. This base class will contain the shared properties.
- Create a static class that contains the shared properties.
- Using dependency injection, create a class that contains the
properties, register it as a singleton in your container and inject
it into your view-model's ctors.
Also, I believe that the EventAggregator
is best suited for communicating between modules/assemblies. In your example, it seems like everything is in the same assembly.