Closing Child Window from ViewModel

2019-09-18 04:54发布

问题:

I have Cancel Command in ViewModel.

Which is bound to a cannel Button in child View.

When i press cancel button it will clear all my unsaved data in viewModel.

Additionally i have to close the current instance of child window.-This is where I am stuck.

I am using MVVM.

回答1:

I use the following pattern.

I have a base class for my ViewModel

public abstract class ClosableViewModel : IClosableViewModel
{
    public event EventHandler Close;

    protected virtual void CloseView()
    {
        var handler = Close;
        if (handler != null) handler(this, EventArgs.Empty);
    }
}

which is implementing this interface

public interface IClosableViewModel
{
    event EventHandler Close;
}

And a window base class for my View I want to show and close via a ViewModel

public class ClosableWindow : Window
{
    public ClosableWindow(IClosableViewModel viewModel)
    {
        DataContext = viewModel;
        viewModel.Close += (s, e) => Close();
    }
}

Your ViewModel which is the DataContext from your View you want to show as dialog has to inherit from ClosableViewModel and your dialog has to inherit from ClosableWindow. When you want to close your View from the ViewModel you just have to call the CloseView method.



回答2:

An alternative to using an event is an attached property that goes on the view. The property changed handler will find the parent window of the view and close it as soon as a particular value is recognized.

using System.Windows;

namespace WpfApp1
{
    public class CloseSignal
    {
        public static readonly DependencyProperty SignalProperty =
            DependencyProperty.RegisterAttached("Signal", typeof(bool), typeof(CloseSignal),
                new PropertyMetadata(OnSignalChanged));

        public static bool GetSignal(DependencyObject dp)
        {
            return (bool)dp.GetValue(SignalProperty);
        }

        public static void SetSignal(DependencyObject dp, bool value)
        {
            dp.SetValue(SignalProperty, value);
        }

        private static void OnSignalChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
        {
            if (!(bool)e.NewValue)
                return;
            Window parent = Window.GetWindow(dp);
            if (parent != null)
                parent.Close();
        }
    }
}

And the view's XAML looks something like...

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp1"
        Title="MainWindow" Height="350" Width="525"
        local:CloseSignal.Signal="{Binding Signal}">
    ...
</Window>


标签: wpf mvvm