WPF MVVM: How to close a window

Bob picture Bob · Dec 7, 2010 · Viewed 130.5k times · Source

I have a Button that closes my window when it's clicked:

<Button x:Name="buttonOk"  IsCancel="True">Ok</Button>

That's fine until I add a Command to the Button i.e.

<Button x:Name="buttonOk" 
        Command="{Binding SaveCommand}" 
        IsCancel="True">Ok</Button>

Now it doesn't close presumably because I am handling the Command. I can fix this by putting an EventHandler in and calling this.Close() i.e.

<Button x:Name="buttonOk" 
        Click="closeWindow" 
        Command="{Binding SaveCommand}" 
        IsCancel="True">Ok</Button>

but now I have code in my code behind i.e. the method SaveCommand. I am using the MVVM pattern and SaveCommand is the only code in my code behind.

How can I do this differently so as not to use code behind?

Answer

Jonathan Shay picture Jonathan Shay · Jun 30, 2013

I just completed a blog post on this very topic. In a nutshell, add an Action property to your ViewModel with get and set accessors. Then define the Action from your View constructor. Finally, invoke your action in the bound command that should close the window.

In the ViewModel:

public Action CloseAction  { get; set;}

and in the View constructor:

private View()
{
    InitializeComponent();
    ViewModel vm = new ViewModel();
    this.DataContext = vm;
    if ( vm.CloseAction == null )
        vm.CloseAction = new Action(this.Close);
}

Finally, in whatever bound command that should close the window, we can simply invoke

CloseAction(); // Calls Close() method of the View

This worked for me, seemed like a fairly elegant solution, and saved me a bunch of coding.