読者です 読者をやめる 読者になる 読者になる

ぺやろぐ

ゲームと奈々ちゃんと時々プログラミング

〔C#〕〔WPF〕閉じる時に行う処理をMVVMで追加する

前回の記事で予告していた通り、「ここが詰まったよ!WPF」シリーズということで第1弾は閉じる時に行う処理の追加についてご紹介します。

第何弾までやるのかは未定です。

目的

コードビハインド側で言うところの「OnClosing()」メソッドに処理を追加することをMVVMで実装する。

経緯

閉じるタイミングで何かしたいときってOnClosingに記述すれば基本的にOKなんですが

protected override void OnClosing(CancelEventArgs e)
{
       base.OnClosing(e);

       // 何か処理追加
}

MVVM的にはこれはよろしくない。(と思っています。)

そこで、どうしようかと考えた結果が以下。(かんろくのソース流用)

実装

見た目を変更して閉じるボタンを自前で用意していることが前提条件です。
デフォルトのままの閉じるボタンに処理の追加は僕にはできませんでした。(情報求ム)
まず、ViewのコンストラクタでModelクラスのCloseActionプロパティにthis.Close()の処理を渡しておきます。

MainWindow.xaml.cs

public MainWindow()
{
     InitializeComponent();

     var mView = new ViewModel.MainViewModel();
     this.All.DataContext = mView;
     // OnClose時に処理を行いたいので、Model側で閉じられるようthis.CloseをVMに渡す。
     if(mView.Model.CloseAction == null)
           mView.Model.CloseAction = new Action(() => this.Close());
}

メソッド名はなんでもいいのですが、わかりやすくOnClosingとしておいたメソッドに、追加したい処理とCloseActionプロパティの呼び出しをします。

MainModel.cs

// 閉じる処理プロパティ

public Action CloseAction { get; set; }

public void OnClosing()
{
     // 追加したい処理
     CloseAction();
}

ViewModelではコンストラクタの中でICommandのCloseにModelクラスのOnClosingメソッドを紐づけさせます。 

MainViewModel.cs

public ICommand Close { get; private set; }

public MainViewModel() 
{

     Close = new RelayCommand(_Model.OnClosing);

}

RelayCommandはGitHubを確認してください。(
KanmusuDrop/RelayCommand.cs at master · peyangu/KanmusuDrop · GitHub
)

それができたら、xamlで閉じるボタンのCommandにCloseをBindしてあげると閉じるときに処理を挟むことができます。

<Button x:Name="CloseButton" Content="r" Style="{DynamicResource CaptionButtonStyleKey}" Command="{Binding Close}">

 

まとめ

かんろくのドロップ情報を保存する処理がまんまこの流れです。

これはこれでどうなのかと思わなくもないですけどね。

一応、コードビハインドを使わずにできたってことで良しとしましょう。

もっといい実装方法あれば教えてください<(_ _)> 

ということで、第1弾「閉じる時に行う処理をMVVMで追加する」でした。