Posted at

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>