Imagine you want a Save & Close
and a Cancel & Close
button on your fancy WPF MVVM window?
How would you go about it? MVVM dictates that you bind the button to an ICommand
and inversion of control dictates that your View
may know your ViewModel
but not the other way around.
Poking around the net I found a solution that has a ViewModel
closing event to which the View
subscribes to like this:
private void OnLoaded(Object sender
, RoutedEventArgs e)
{
IFilterViewModel viewModel = (IFilterViewModel)DataContext;
viewModel.Closing += OnViewModelClosing;
}
private void OnViewModelClosing(Object sender
, EventArgs<Result> e)
{
IFilterViewModel viewModel = (IFilterViewModel)DataContext;
viewModel.Closing -= OnViewModelClosing;
DialogResult = (e.Value == Result.OK) ? true : false;
Close();
}
But that is code-behind mixed in with my so far very well designed MVVM.
Another problem would be showing a licensing problem message box upon showing the main window. Again I could use the Window
.Loaded
event like I did above, but that's also breaking MVVM, is it not?
Is there a clean way or should one be pragmatical instead of pedantic in these cases?
First, create an interface that contains only the Close
method:
interface IClosable
{
void Close();
}
Next, make your window implement IClosable
:
class MyWindow : Window, IClosable
{
public MyWindow()
{
InitializeComponent();
}
}
Then let the view pass itself as IClosable
as command parameter to the view model:
<Button Command="{Binding CloseCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
And lastly, the command calls Close
:
CloseCommand = new DelegateCommand<IClosable>( view => view.Close() );
And what have we now?
, IClosable
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