22

In a MVVM WPF application.

How do you set a second windows parent from the ViewModel?

example:

view1 -- viewModel1

viewModel1's command calls:

var view2 = new view2

view2.Owner = <----This is the problem area. How do I get view1 as the owner here from the viewModel?

view2.Show()

EDIT:

See accepted answer below, then read the following edit.

I'am using MVVM light -> http://mvvmlight.codeplex.com/ (awesome btw)

The baked-in messaging system is great. I am now sending a message from the viewmodel to my view telling it to show another window.

For the message I'am currently using a string with a switch statement in the main view to determine what view to open; however I may tinker with the tokens that also are part of MVVM light toolkit.

Thank you!

Andrey Gordeev
  • 30,606
  • 13
  • 135
  • 162
dnndeveloper
  • 1,631
  • 2
  • 19
  • 36
  • Hi dnndeveloper, when you say you are sending message from viewmodel to view telling it to show another window, do you mean you are receving that message and creating/showing another window inside view1 code behind? – nabeelfarid Jul 30 '10 at 11:05
  • nabeelfarid - yes, message is received in the code behind and then after the message has been parsed it will show the appropriate window. – dnndeveloper Aug 03 '10 at 17:19

5 Answers5

26

In my opinion, opening a new window is the responsibility of the View, not of the ViewModel. Personally, I would use the same approach as used for displaying a dialog box (this was discussed in this forum already):

Have the ViewModel send a Message to the View requesting that it opens a new Window. (alternatively) use an IDialogService or whatever you want to call it which you pass to the ViewModel's constructor. This service will be in charge of opening the Window (or of delegating this task to the View). This way, you keep a clean separation of concerns and your VM remains testable (you can unit test that the request to open the new WIndow has been sent, but you couldn't test that the window has been, indeed, open).

Does that make sense?

Cheers,

Laurent

LBugnion
  • 6,672
  • 2
  • 24
  • 28
  • Hi Laurent, How should I send message from ViewModel1 to View1 that will open a new View2? Do you mean the message will be recieved in the code behind of View 1 ? Because I thought the messaging should happen between the viewmodels in mvvm. Or have I got it totally wrong. Sorry I am new to mvvm and wpf and I am using your mvvm light toolkit. – nabeelfarid Jul 30 '10 at 10:59
  • 6
    And when using IDialogService for opening new window, how would I setup the owner property for the new window/view2 as I would need reference to window1/view1, and the viewmodel1 does not contain reference to view1 ? So I think the dialogService will delegate the task to the view1 via messaging and I still not sure how view1 will reveive the message and handle it unless done in view1 codebehind? – nabeelfarid Jul 30 '10 at 11:38
  • Hi Laurent, Could you please clarify where the code for handling the message (that will create a new view2) sent by ViewModel1 should reside? In code behind of View1 ? – nabeelfarid Aug 02 '10 at 09:05
  • @nabeelfarid In LBugnion's MVVM light there is Messenger.Default.Send – Lei Yang Jan 10 '14 at 03:54
  • 1
    Small question, if you create a service, and this service receives only a ViewModel, how the service would be able to set the owner to the new window? – J4N Mar 09 '16 at 14:47
8

From your viewmodel call

Messenger.Default.Send<NotificationMessage>(new NotificationMessage("Open Window"));

And from your view's codebehind (a view that call the second view) easily write this in the constructor:

Messenger.Default.Register<NotificationMessage>(this, ReplyToMessage);

And also write this method in the view's codebehind:

private void ReplyToMessage(NotificationMessage msg)
{
   if (msg.Notification == "Open Window")
   {
      SecondWindow win = new SecondWindow();
      win.ShowDialog();
   }
}
Mohammad Zare
  • 1,489
  • 7
  • 25
  • 45
1

I don't have an answer of my own but here's a few links to things I've been looking at lately that might help. I'll also be interested in anything others suggest.

As I understand it, the key thing is, you shouldn't be creating Views from within a View Model if possible, so you need a means of communicating what you need in a loosely coupled fashion.

http://www.codeproject.com/KB/WPF/XAMLDialog.aspx

http://www.codeproject.com/KB/architecture/MVVM_Dialogs.aspx

Handling Dialogs in WPF with MVVM

Community
  • 1
  • 1
Grokodile
  • 3,881
  • 5
  • 33
  • 59
0

Prism-Event Aggrigator is good approach, where we can create independent module without dependency. first viewmodel will publish event and then another view or view or viewmodel can subscribe that event from event aggrigator.

in this case Unity container can also use to inject one viewmodel in to another with dependency injection.

Jitendra
  • 1
  • 2
0

You can do in this way like you need to create some events and register those in view and call these in view model.and open that pop up window.

Like This example

public class Mainclass : MainView
{
  public delegate abc RegisterPopUp(abc A);
  public RegisterPopUp POpUpEvent;

  public RelayCommand ShowCommand { private set; get; }  

  public void ShowCommand() 
  { 
    ShowCommand("Your parameter");
  } 
}

inside the view

MainView mn = new MainView();

Register the event here like mn.POpUpEvent += then click on tab button double time and in registers popup method write the code for opening the pop up window.

dove
  • 20,469
  • 14
  • 82
  • 108
Hoshiyar
  • 31
  • 1