So my first attempt did everything out of the code behind, and now I\'m trying to refactor my code to use the MVVM pattern, following the guidance of the MVVM in the box inf
Here is the simplest and pure MVVM solution
ViewModel Code
public class ViewModel
{
public Action CloseAction { get; set; }
private void CloseCommandFunction()
{
CloseAction();
}
}
Here is XAML View Code
public partial class DialogWindow : Window
{
public DialogWindow()
{
ViewModel vm = new ViewModel();
this.DataContext = vm;
vm.CloseAction = new Action(() => this.Close());
}
}
first of all give your window a name like
x:Name="AboutViewWindow"
on my close button I've defined Command and Command Parameter like
CommandParameter="{Binding ElementName=AboutViewWindow}"
Command="{Binding CancelCommand}"
then in my view model
private ICommand _cancelCommand;
public ICommand CancelCommand
{
get
{
if (_cancelCommand == null)
{
_cancelCommand = new DelegateCommand<Window>(
x =>
{
x?.Close();
});
}
return _cancelCommand;
}
}
I personally use a very simple approach: for every ViewModel that is related to a closeable View, I created a base ViewModel like this following example:
public abstract class CloseableViewModel
{
public event EventHandler ClosingRequest;
protected void OnClosingRequest()
{
if (this.ClosingRequest != null)
{
this.ClosingRequest(this, EventArgs.Empty);
}
}
}
Then in your ViewModel that inherits from CloseableViewModel
, simply call this.OnClosingRequest();
for the Close
command.
In the view:
public class YourView
{
...
var vm = new ClosableViewModel();
this.Datacontext = vm;
vm.ClosingRequest += (sender, e) => this.Close();
}
Given a way, Please check
https://stackoverflow.com/a/30546407/3659387
Short Description
You don't need to pass the View instance to your ViewModel layer. You can access the main window like this -
Application.Current.MainWindow.Close()
I see no issue in accessing your main window in ViewModel class as stated above. As per MVVM principle there should not be tight coupling between your View and ViewModel i.e. they should work be oblivious of others operation. Here, we are not passing anything to ViewModel from View. If you want to look for other options this might help you - Close window using MVVM
This is very similar to eoldre's answer. It's functionally the same in that it looks through the same Windows collection for a window that has the view model as its datacontext; but I've used a RelayCommand and some LINQ to achieve the same result.
public RelayCommand CloseCommand
{
get
{
return new RelayCommand(() => Application.Current.Windows
.Cast<Window>()
.Single(w => w.DataContext == this)
.Close());
}
}