0

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?

mathgenius
  • 503
  • 1
  • 6
  • 21

0 Answers0