4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【WPF】ViewModelからWindowを閉じる方法の1つ

Last updated at Posted at 2020-08-15

この記事は何か

WPFでアプリを作っている。
ViewModelからWindowを閉じる方法を探したが、どれもピンと来なかった。
いろいろな記事から良いとこ取りをした、自分なりの結論(方法)を書く。

(想定)

  • Window1.xamlにボタンが1つ配置されている。
  • そのボタンをクリックすると、Windowが閉じる。

View

ボタンの親Windowを探して、それを引数にCloseWindowを実行する。
CloseWindowは後述のViewModelに実装する。

Window1.xaml
<Button Command="{Binding CloseWindow}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Content="Close" />

#ViewModel
ReactivePropertyでコマンドを宣言し、コンストラクタ内に処理の内容を書く。

System.Windows.Windowで安直にキャストして.Close()しているけど、
本当はちゃんとnullチェックとかした方がいい。

Window1ViewModel.cs
// プロパティ宣言
public ReactiveCommand CloseWindow { get; } = new ReactiveCommand();

// コンストラクタ内
CloseWindow.Subscribe(x => ((System.Windows.Window)x).Close());

#使い道
ウィンドウ内の OK/キャンセル ボタンを押して
すぐにウィンドウを閉じるのではなく
確認ダイヤログを表示してからウィンドウを閉じたい場合。

Window1.xaml
<Button Command="{Binding OK}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Content="OKボタン" />
Window1ViewModel.cs
// コンストラクタ内
OK.Subscribe(x => {
    result = MessageBox.Show("ウィンドウを閉じてもよろしいですか?", "確認メッセージ", MessageBoxButtons.OKCancel);
    if (result == DialogResult.Cancel)
        return;
    else
        CloseWindow.Execute(x);
});

#最後に

きっと、もっといい方法があると信じている

#参考
xamlだけでウィンドウを閉じる処理を実装 (www.neko3cs.net 様)

#追記2020.08.17
コメントいただき、TriggerActionでググったら、あっという間に正解にたどり着きました。
MVVMでウインドウを閉じる - Qiita

もっとちゃんと検索してから記事を書きます。
ありがとうございました。

#追記2020.08.27
コメントで関連動画を紹介いただきました。ありがとうございます。
YouTubeの動画 (イントロを飛ばして開始120秒から再生)

4
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?