views:

731

answers:

3

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!

A: 

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

http://stackoverflow.com/questions/454868/handling-dialogs-in-wpf-with-mvvm

panamack
+1  A: 

One solution would be to pass View1 into ViewModel1 when you create your View1.

Something like this:

public void BuildView1()
{
    var view1 = new View1();
    var viewModel1 = new ViewModel1(view1); // pass in view1 here
    view1.DataContext = viewModel1;
}

Then, in your ViewModel1, put something like this:

public class ViewModel1: ObservableObject
{
    private View1 _view1;

    public ViewModel1(View1 view1)
    {
        _view1 = view1; // store view1
    }

    private void BuildView2()
    {
        var view2 = new View2();
        var viewModel2 = new ViewModel2();
        view2.DataContext = viewModel2;
        view2.Owner = _view1; // set the owner
    }
}
DanM
+4  A: 

Hi,

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
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
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
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