Reputation: 993
I have my MainView
and an associated MainViewViewModel
which are linked by ViewModelLocator
.
Within MainViewViewModel
there is a command which should trigger a new Window
to open which has it's own View and ViewModel (NewView
and NewViewViewModel
).
In a lot of the examples I've seen it is suggested to use Mvvmlight's Messenger
to do something like this:
public class MainViewViewModel
{
private void OpenNewWindow()
{
Messenger.Default.Send(new NotificationMessage("NewView"));
}
}
And then register the NewViewViewModel
and handle the message like this:
public class NewViewViewModel
{
public NewViewViewModel()
{
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage obj)
{
if (obj.Notification == "NewView")
{
NewView view = new NewView();
view.Show();
}
}
}
However, this doesn't work because the NewViewViewModel isn't yet instantiated (so isn't registered with Messenger
). Additionally, this doesn't fit with MVVM because NewViewViewModel
is responsible for creating NewView
.
What is the correct way to achieve a simple command which instantiates and opens a new View and ViewModel pair which are linked via ViewModelLocator
and setting of DataContext="{Binding NewView, Source={StaticResource Locator}}"
in NewView.xml
?
Upvotes: 0
Views: 251
Reputation: 169150
Use a window service:
MVVM show new window from VM when seperated projects
You may either inject the view model to with an IWindowService
implementation or use a static WindowService
class:
public static class WindowService
{
public static void OpenWindow()
{
NewView view = new NewView();
view.Show();
}
}
Dependency injection is obviously preferable for being able to unit test the view model(s) and switch implementations of IWindowService
at runtime.
Upvotes: 3