WPF MVVM: How to close a window

后端 未结 21 1716
后悔当初
后悔当初 2020-12-04 08:19

I have a Button that closes my window when it\'s clicked:


相关标签:
21条回答
  • 2020-12-04 09:00

    I also had to deal with this problem, so here my solution. It works great for me.

    1. Create class DelegateCommand

        public class DelegateCommand<T> : ICommand
    {
        private Predicate<T> _canExecuteMethod;
        private readonly Action<T> _executeMethod;
        public event EventHandler CanExecuteChanged;
    
        public DelegateCommand(Action<T> executeMethod) : this(executeMethod, null)
        {
        }
        public DelegateCommand(Action<T> executeMethod, Predicate<T> canExecuteMethod)
        {
            this._canExecuteMethod = canExecuteMethod;
            this._executeMethod = executeMethod ?? throw new ArgumentNullException(nameof(executeMethod), "Command is not specified."); 
        }
    
    
        public void RaiseCanExecuteChanged()
        {
            if (this.CanExecuteChanged != null)
                CanExecuteChanged(this, null);
        }
        public bool CanExecute(object parameter)
        {
            return _canExecuteMethod == null || _canExecuteMethod((T)parameter) == true;
        }
    
        public void Execute(object parameter)
        {
            _executeMethod((T)parameter);
        }
    }
    

    2. Define your command

            public DelegateCommand<Window> CloseWindowCommand { get; private set; }
    
    
        public MyViewModel()//ctor of your viewmodel
        {
            //do something
    
            CloseWindowCommand = new DelegateCommand<Window>(CloseWindow);
    
    
        }
            public void CloseWindow(Window win) // this method is also in your viewmodel
        {
            //do something
            win?.Close();
        }
    

    3. Bind your command in the view

    public MyView(Window win) //ctor of your view, window as parameter
        {
            InitializeComponent();
            MyButton.CommandParameter = win;
            MyButton.Command = ((MyViewModel)this.DataContext).CloseWindowCommand;
        }
    

    4. And now the window

      Window win = new Window()
            {
                Title = "My Window",
                Height = 800,
                Width = 800,
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
    
            };
            win.Content = new MyView(win);
            win.ShowDialog();
    

    so thats it, you can also bind the command in the xaml file and find the window with FindAncestor and bind it to the command parameter.

    0 讨论(0)
  • 2020-12-04 09:00

    You can do it without code behind. Create command, in Execute method call "Save" method on viewmodel and after that call close method on edit window, which you can pass to the command by parameter:

    public void Execute(object parameter)
    {
        _mainViewModel.SaveSomething();
        var editWindow = parameter as MyEditWindow;
        editWindow?.Close();
    }
    

    Save&Close button XAML:

    <Button Content"Save&Close" Command="{Binding SaveCmd}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"  IsDefault="True" />
    
    0 讨论(0)
  • 2020-12-04 09:01

    Very clean and MVVM way is to use InteractionTrigger and CallMethodAction defined in Microsoft.Interactivity.Core

    You will need to add a new namespace as below

    xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
    

    You will need the Microsoft.Xmal.Behaviours.Wpf assembly and then the below xaml code will work.

    <Button Content="Save" Command="{Binding SaveCommand}">
      <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
          <i:CallMethodAction MethodName="Close"
                               TargetObject="{Binding RelativeSource={RelativeSource
                                                      Mode=FindAncestor,
                                                      AncestorType=Window}}" />
        </i:EventTrigger>
      </i:Interaction.Triggers>
    </Button>
    

    You don't need any code behind or anything else and can also call any other method of Window.

    0 讨论(0)
提交回复
热议问题