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?
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.
Very clean and MVVM way is to use InteractionTrigger
and CallMethodAction
defined in Microsoft.Interactivity.Core
You will need to add a new namespace as below
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
You will need the Microsoft.Xmal.Behaviours.Wpf assembly and then the below xaml code will work.
<Button Content="Save" Command="{Binding SaveCommand}"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" /> </i:EventTrigger> </i:Interaction.Triggers> </Button>
You don't need any code behind or anything else and can also call any other method of Window
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With