質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

4261閲覧

MVVMでViewModelに対してModelから処理を行いたい

siksmtt

総合スコア20

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2020/04/16 02:02

質問

WPFアプリケーションをMVVMで開発しています。
アプリケーションの仕様としてバックグラウンドスレッド(Model)で常に動いている処理があるのですが、
その処理が MainWindow の ViewModel に対して処理を行いたい場合、ViewModel の実装はどのようにすればいいのでしょうか?

以前質問したコードを例とすると
バックグラウンドスレッドでprivate void Button_Click()と同じ処理をしたい場合
MVVM では Model は ViewModel を知らないという解釈なので、Model に ViewModel のインスタンスを渡したりすることは禁じ手なのかなと考えています。

そのため解決するとしたら

  • ViewModel(public class MainViewModel) を Model としてそのまま実装する
  • ViewModel を Model として実装するが MainWindow と Model がバインドすることになるので、Model をラップした ViewModel を新たに実装する
  • ViewModel の private 変数のみ(private ObservableCollection<string> listValなど)を Model として実装し、処理は private 変数に対して行う

上記が考えられるのですがどのようにするのがMVVMとしては相応しいのでしょうか?
個人的には今のところは最後の案がベストなのかなと考えているのですが、
private 変数の更新を ViewModel がどのように検知するか、という点についてはまだ分かっていません。

プロジェクトの方針などにもよると思うので正解はないとは思っているのですが、
ご助言いただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/04/16 02:46

モデルはビューモデルに依存しないよう作るので、直接操作できません。 ビューモデルの方でモデルのイベントを購読するか、メッセンジャーを使います。
siksmtt

2020/04/16 05:02

Zuishin様 ご指摘ありがとうございます。なるほど、色々調べてはいましたがイベント購読やメッセンジャーはこういうときに活躍するのですね...。イベント購読についてはメモリリークの問題も挙げられているようなので、注意して実装していきたいと思います。
Zuishin

2020/04/16 05:14

イベント購読によるメモリリークは、イベントを購読する方がイベントを発生させる方よりも寿命が短い時に起こります。 例えば、ウィンドウを開くたびに新しくウィンドウを作成するような仕様の場合、破棄されたウィンドウがモデルのイベントを捕まえているためにインスタンスが解放されず、メモリリークします。この時モデルは、既に画面から消え去っている全てのウィンドウにイベントを送り続けることになります。 これを防止するには、ウィンドウが破棄されるタイミングでイベントの購読をやめるか、ウィンドウが閉じても破棄せず、次に開く時に同じインスタンスを再利用するしくみ(シングルトンなどを使う)を採用してください。 なお、プロセス終了時にアプリの使用していたメモリは全て解放されるので、メインウィンドウとそのビューモデル(つまり一番寿命の長いオブジェクト)は、その心配の必要はありません。購読しっぱなしで大丈夫です。
Zuishin

2020/04/16 05:23 編集

あと、モデル作成をビューモデルで行ってモデルのインスタンスをビューモデルのみで保持する場合、ビューモデルとモデルの寿命は同じになるので、この場合も気にする必要はありません。 この場合、互いに参照しあう形になりますが、他のオブジェクトのスコープから両者が消えた段階で双方ガベージコレクション対象になります。
siksmtt

2020/04/16 05:30

Zuishin様 補足までありがとうございます...!例えも教えていただいてとても参考になりました。
guest

回答1

0

ベストアンサー

めっちゃ雑に回答すると

バックグラウンドスレッド、とやらが何か処理をする→処理をした結果、Modelの状態(プロパティ)が変化する→ViewModelはそのModelの状態変更が起こったことで発生するイベントで、変更を検知する→ViewModelの状態が変わる→Viewに反映される。

という作りになるのが一般的では。

たぶん色んな解説記事読んでコード動かしながらじゃないと腑に落ちないと思うけど、質問文にあるような解決策は全て基本やらないと思います。

投稿2020/04/16 04:13

gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siksmtt

2020/04/16 05:06

gentaro様 ご回答ありがとうございます。ViewModelでModelのイベントを購読するような形という認識で正しいでしょうか?ひとまず自分の考えているような解決策は一般的ではないことを理解できたので、他のサンプルなどをじっくり見て動かして理解しようと思います!もし認識相違があればご指摘ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問