0

I am using MVVM, from one I know the commnication for Data is View <=> ViewModel <=> Model.

The ViewModel can interact with View by using Two-Way binding.

But now I have a LoginView (which is in a Window), if the login successful will be check in ViewModel.

When it fail, it should tell the Window to close. But...how? The ViewModel is not suppose to know about the View....

King Chan
  • 4,212
  • 10
  • 46
  • 78
  • Fire an event and let the view respond to it? – vcsjones Jan 19 '12 at 16:45
  • Possible duplicate [here](http://stackoverflow.com/questions/501886/wpf-mvvm-newbie-how-should-the-viewmodel-close-the-form). – docmanhattan Jan 19 '12 at 16:53
  • We tend to break the usual MVVM rules here, our WindowViewModel knows about its window, otherwise it would be really difficult to handle windows correctly. After that we never touch the View from the ViewModels and it works perfectly. – dowhilefor Jan 19 '12 at 16:56
  • @docmanhattan omg, the answer is genius lol Thanks – King Chan Jan 19 '12 at 16:58

4 Answers4

7

Your ViewModel is a representation of your UI state. You could simply have a IsLoginWindowVisible boolean property exposed, your view can then have code (yes, I said it, view can have code!) that shows / hides a windows based on the state of this property.

I think people stress too much about MVVM. As long as your ViewModel can execute without a view present, in order to facilitate testing, you are doing MVVM correctly. There is nothing wrong with having code to support your view.

ColinE
  • 68,894
  • 15
  • 164
  • 232
  • +1 Something i always wondered: Where did the people get the idea that in MVVM absolutely no code is allowed in the view?! Its like using goto for some people, to tell them to write code in the view. As long as it is not business relevant its imho perfectly valid and the best solution to extend and add code to the view, via subclassing or attached behaviors. – dowhilefor Jan 19 '12 at 16:50
  • @dowhilefor I have no idea why people think that! there is some argument if you use Blend and design-time data. However, how many people use Blend for their WPF apps? – ColinE Jan 19 '12 at 16:58
  • @dowhilefor I always got affected by the example I read, they keep on showing how they can made the View without any code-behind and working prefectly. Sometime I do wonder is it fine if I just do some hack and break some MVVM rules? But then I always think the example that people wrote should be a better solution than I do lol – King Chan Jan 19 '12 at 17:02
  • @ColinE I did use Blend sometime, but then it just really hard for me to work for ACTUAL application that has dynamic controls, hooking up controls and different stuff... But I wonder.. if that's just because I am not skillful enough in Blend.... – King Chan Jan 19 '12 at 17:04
  • @ColinE +1 "Yes I said it, view can have code!". Calling the MVVM purist police now ... – Dr. Andrew Burnett-Thompson Jan 21 '12 at 17:15
0

I would go simple here and use an event to notify the view it should close.

ViewModel:

public event EventHandler LoginFailed;

public void Login()
{
    if (fail)
    {
        if (this.LoginFailed != null)
        {
            this.LoginFailed(this, EventArgs.Empty);
        }
    }
}

View:

((MyViewModel)this.DataContext).LoginFailed += (sender, e) =>
    {
        // Code to close the window, such as window.Close();
    };
ken2k
  • 48,145
  • 10
  • 116
  • 176
0

You should add a specific event to your ViewModel (something like LoginFailed). Then you should link this event to a command that closes the window. See this blog post on how to link the two.

CosminB
  • 173
  • 8
0

Here's another option. Instead of using an event you could use a delegate:

public class View {
    ...
    myViewModel.OnFail = () => {this.Close();};
    ...
}

public class MyViewModel {
    public Action OnFail {get; set;}

    private void Login() {
        ....
        if (failed && OnFail != null)
            OnFail();
    }
}
Mike
  • 753
  • 1
  • 7
  • 16