Home > Technology > One way to manage an ‘OK’ button with WPF / MVVM

One way to manage an ‘OK’ button with WPF / MVVM

November 20th, 2009 Leave a comment Go to comments

I am using the M-V-VM pattern on a WPF app. The rules that we are following on my team state that the View only knows about the ViewModel via the DataContext. The ViewModel has no explicit knowledge of the View.

BTW: I created the project using the WPF M-V-VM template available on CodePlex (I think?). It already contains the DelegateCommand classes.

I have an “OK” button.

In WPF, a button does nothing. If you want to do do “something” you have to wire up a command that resides in the ViewModel.

View:

<Button Command="{Binding UserClickedOkButtonCommand}" Content="OK" />

 

ViewModel:

public ICommand UserClickedOkButtonCommand { get { return new DelegateCommand( UserClickedOkButton); } }

public void UserClickedOkButton()
{
// do something
}

 

If you put a break point on the UserClickedOkButton, you will see the event is correctly mapped to the delegate method. So how do I close the View?

It takes a couple extra steps to get all of your ducks in a row.

First, add an x:Name=”ThisWindowName” to your View header.
Second, add a command parameter that refers back to your new window name.
Third, update the Command in the ViewModel to use a Window as it’s argument.
Fourth, use the input window argument to close the window.

Here’s the code.

View:

<Window
	...
	x:Name="ThisWindowName"
>
...
<Button Command="{Binding UserClickedOkButtonCommand}" CommandParameter="{Binding ElementName=ThisWindowName, Path=.}" Content="OK" />

 

ViewModel:

public ICommand UserClickedOkButtonCommand { get { return new DelegateCommand( UserClickedOkButton); } }

public void UserClickedOkButton(Window window)
{
	// Do Something
	window.Close();
}

The window is closed. Concerns are separated. MVVM rules are followed.

Works on my machine.

  1. December 9th, 2009 at 11:17 | #1

    I found another way to do this, sort of. Set the binding via ancestory to the parent window.

    {Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=.}
    

    In fact this doesn’t really work. The problem is the path. You can define any child element via the path reference, btu I have not seen an easy way to define the einter window in the path. “.” doesn’t work. I’d imagine there is a way to do it with something like {RelativeSource Self} but I have not had time to research this further.

    Why not? What I’ve got works and reworking existing code is kind of a waste of time when I’m not feature complete yet.

  1. No trackbacks yet.
You must be logged in to post a comment.