I have a WPF app in which I use Windows to house UserControls which contain all the actual controls and whose ViewModels do all the actual work. In other words the Windows don't do anything besides be a graphical container for my UserControls (I believe this is a good practice?). I am marrying the views and viewmodels by use of the ViewModelLocator pattern, shown below:
namespace Frontend
{
/// <summary>
/// Locates and "marries" views to their corresponding viewmodels,
/// provided they follow the standard naming convention.
/// </summary>
public static class ViewModelLocator
{
public static bool GetAutoWireViewModel(DependencyObject obj)
{
return (bool)obj.GetValue(AutoWireViewModelProperty);
}
public static void SetAutoWireViewModel(DependencyObject obj, bool value)
{
obj.SetValue(AutoWireViewModelProperty, value);
}
// Using a DependencyProperty as the backing store for AutoWireViewModel. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AutoWireViewModelProperty =
DependencyProperty.RegisterAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), new PropertyMetadata(false, AutoWireViewModelChanged));
private static void AutoWireViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (DesignerProperties.GetIsInDesignMode(d)) return;
var viewType = d.GetType();
var viewTypeName = viewType.FullName;
var viewModelTypeName = viewTypeName.Replace("View", "ViewModel");
var viewModelType = Type.GetType(viewModelTypeName);
var viewModel = Activator.CreateInstance(viewModelType);
((FrameworkElement)d).DataContext = viewModel;
}
}
}
Using this pattern makes the views and viewmodels sort themselves out, which is great, but I don't have any reference to the view from the viewmodel, so now I want to be able to click a button in a UserControl and close the Window containing it.
I use RelayCommand
and Binding
to execute the command.
Is there a better way to close the current window than to use var window = Application.Current.Windows[0];
to get a reference to the currently open window, and then close it?