C#
WPF
Xaml
MVVM

MVVMでウィンドウのクローズをキャンセルする

やりたいこと

WindowのClosingイベント発生時にModelViewのメソッドを実行したい。ただし、クローズをキャンセルできるようにする。

実装

呼び出したいメソッドをインターフェイスに定義しておき、イベント発生時にView側から実行する。インターフェイスを使うことでViewがViewModelのクラスを知らずに済む。

インターフェイス
namespace Sample {
    public interface IClosing {
        bool OnClosing();
    }
}
ビヘイビア
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Interactivity;

namespace Sample {
    public class WindowClosingBehavior : Behavior<Window> {
        protected override void OnAttached() {
            base.OnAttached();

            AssociatedObject.Closing += Window_Closing;
        }

        protected override void OnDetaching() {
            base.OnDetaching();

            AssociatedObject.Closing -= Window_Closing;
        }

        private void Window_Closing(object sender, CancelEventArgs e) {
            var window = sender as Window;

            //ViewModelがインターフェイスを実装していたらメソッドを実行する
            if (window.DataContext is IClosing)
                e.Cancel = (window.DataContext as IClosing).OnClosing();
        }
    }
}
XAML
<Window x:Class="Sample.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:local="clr-namespace:Sample"
        Title="MainView" Height="300" Width="300">
    <i:Interaction.Behaviors>
        <local:WindowClosingBehavior />
    </i:Interaction.Behaviors>
    <Grid>
        <TextBox />
    </Grid>
</Window>