Implementing “close window” command with MVVM

后端 未结 12 1671
既然无缘
既然无缘 2020-12-05 09:31

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

相关标签:
12条回答
  • 2020-12-05 10:09

    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());
        }
    }
    
    0 讨论(0)
  • 2020-12-05 10:09

    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;          
         }      
    }
    
    0 讨论(0)
  • 2020-12-05 10:13

    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();
    }
    
    0 讨论(0)
  • 2020-12-05 10:14

    Given a way, Please check

    https://stackoverflow.com/a/30546407/3659387

    Short Description

    1. Derive your ViewModel from INotifyPropertyChanged
    2. Create a observable property CloseDialog in ViewModel, Change CloseDialog property whenever you want to close the dialog.
    3. Attach a Handler in View for this property change
    4. Now you are almost done. In the event handler make DialogResult = true
    0 讨论(0)
  • 2020-12-05 10:17

    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

    0 讨论(0)
  • 2020-12-05 10:20

    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());
        }
    }
    
    0 讨论(0)
提交回复
热议问题