-3

I have a ViewModel with some internal code that need to close the window that my viewmodel is bound to. So far I have:

MyWindow.xaml.cs

public class MyWindow : Window
{
    public MyWindow()
    {
        InitializeComponent();

        DataContext = new MyVM(this);
    }
}

MyVM.cs

public class MyVM
{
    public MyVM(MyWindow owner)
    {
        Owner = owner;
    }

    public MyWindow Owner { get; }

    public void SomeAction()
    {
        Owner.Close();
    }
}

This works perfectly, but I created a dependency between MyVM with My Window that is not needed, or at least not intended.

So here is my question: Is there a way to Close a window without has directly pass the reference of the window to the view model?

UPDATE - Possible Duplicate:

Different of the question and the accepted answer, I don't have any command bind I cannot pass the window as command parameter.

The possible duplicate question show some vm code binded as command to a button. I'm not trying to execute Window.Close() inside a command bind scope.

Community
  • 1
  • 1
Jonny Piazzi
  • 3,684
  • 4
  • 34
  • 81
  • To decouple the V and the VM you could use a Command and a EventAggregator. – Batuu May 09 '16 at 18:47
  • You can generate an event in your MVVM to which you would subscribe in View. – ixSci May 09 '16 at 18:55
  • Can you show me how to do this? – Jonny Piazzi May 09 '16 at 19:08
  • @JonnyPiazzi there's about 400-5000 tutorials/blog articles on this very scenario – Dbl May 09 '16 at 19:09
  • Possible duplicate of [Close Window from ViewModel](http://stackoverflow.com/questions/16172462/close-window-from-viewmodel) – Dbl May 09 '16 at 19:12
  • I'm searching for 3 days now and I already read 100 of them, but not quite fix my problem. My question was updated and I'm my very clear that the duplication is applicable here, please undo it. – Jonny Piazzi May 09 '16 at 20:44

2 Answers2

1

If you use a framework, they often have a messenger system that broadcasts messages for the entire programme to listen to. A simple system has a close window message that is broadcast and only listened for by windows, therefore allowing View Models to broadcast that they want their window closing, and only their window receives it.

On the MVVMLight website, there is a Blog about using their messenger system to safely shut down an application, allowing all parts of the application to correctly clean up before being shut down:

http://blog.galasoft.ch/posts/2009/10/clean-shutdown-in-silverlight-and-wpf-applications/

Jonathan Twite
  • 932
  • 10
  • 24
0

In MVVM, the ViewModel shouldn't be aware of any UI classes, let alone know the specific View object that it's linked to.

For a completely decoupled solution, you can create an attached property on the View window, which can then be bound to an appropriate property on the ViewModel. The top rated answer to this question has the details.

If you want to apply this methodology to non-modal as well as modal windows, a small tweak to this code is required.

private static void DialogResultChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
{
    var window = target as Window;

    if (window == null)
        return;

    if (window.IsModal())
        window.DialogResult = args.NewValue as bool?;
    else
        window.Close();
}

where IsModel() is defined as a Window extension method

public static class WindowExtender
{
    public static bool IsModal(this Window window)
    {
        var fieldInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic);
        return fieldInfo != null && (bool)fieldInfo.GetValue(window);
    }
}
Community
  • 1
  • 1
Peregrine
  • 4,287
  • 3
  • 17
  • 34