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

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

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

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

WPF

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

Q&A

解決済

2回答

13608閲覧

MVVMにて、異なるview間での情報共有方法

juntaro

総合スコア15

MVVM

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

WPF

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

0グッド

0クリップ

投稿2018/06/20 06:30

編集2018/06/21 07:31

MVVMの構造に関して、質問させてください。
あるviewの情報を他の画面(view等)から変更する場合、MVVMとしてどういった構造を持つべきでしょうか?
想定としては、常に表示しているviewの背景色等を、他の設定画面やメニューから変更する場合などです。
メニュー等からの変更をどのようにしてviewに伝えてあげれば良いのでしょうか?

熟練者の方々には簡単なお話かと思いますが、初心者ゆえ全くアイデアが出ず、質問させて頂きました。
宜しくお願い致します。

開発環境:Visual Studio 2017 (WPF)
動作環境:Windows10

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

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

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

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

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

guest

回答2

0

ベストアンサー

設定系の情報は共通の ViewModel に分けて定義し、個別画面毎の ViewModel にその参照を持たせる形に私はしています。
同じ1つの ViewModel を見ることによって設定画面での変更が即座に反映できるというわけです!(逆に個別画面側で変更した内容を設定画面に即座に反映することもできる)。

個別画面の ViewModel に設定情報のような共通 ViewModel の参照を設定する具体的な方法としては MVVM のフレームワークである Prism の DI コンテナを使用することを個人的にはお勧めします。

また、単に設定値の表示だけではなく、設定変更後に何らかの計算をする必要がある場合、個別画面毎の ViewModel で設定側の ViewModel の変更を監視することができます。

ViewModel の監視は ReactiveProperty というライブラリを使うのがお勧めです。

(追記)Binding だけで行う簡易的な方法

過去に使っていた Binding だけで行う簡易的な方法を思い出したので追記します。
設定系ViewModelをシングルトンにするのが許容できるのであれば、個別画面側のXAMLにObjectDataProviderで設定系ViewModelのシングルトンをリソースとして定義し、Bindingできます。
以下みたいな感じです。

  • リソース定義(XxxConfig.Instance アクセサでシングルトンが参照できる前提)

C#

1<ObjectDataProvider x:Key="XxxConfig" ObjectInstance="{x:Static Member=local:XxxConfig.Instance}" />
  • リソースの参照個所 Binding

XML

1<ComboBox SelectedValue="{Binding Source={StaticResource XxxConfig}, Path=ConfigProperty1}"> 2 <!-- ... --> 3</ComboBox>

投稿2018/06/24 06:01

編集2018/06/25 13:55
toydev

総合スコア297

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

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

juntaro

2018/06/25 05:41

ありがとうございます。 共通のViewModelそのものを個別画面のViewModelから参照するということですね。 そして、そのままBindingする方向でシステム構築したいと思います。 ご指示頂きましたリンクを見させて頂きました。 既にシステムはLivetでの構築がすすんでおります。 Prismにしておいた方が良かったかと思いつつも、当面はLivetを採用しようと思います。 適切なご指示ありがとうございました。
toydev

2018/06/25 13:53 編集

お気付きの通り、必ずしもPrismを使う必要はありません! Prismを使い始める前は、設定系のViewModelをシングルトンにして各画面に埋め込んでいたのを思い出しました。 Bindingだけで済む内容であればその方法を使うこともできるので、本文に追記書きしておきました。 XAMLに書くだけでよく、個別画面系のViewModelを作り替える必要もないので、簡易な方法として参考にしてみてください。
juntaro

2018/06/29 05:57

ありがとうございます。 本文に追記書きってできるんですね。初めて知りました。 こういったシングルトンのモデルを使用して、ダイアログ等で設定メニューを作成した場合、 バインディング元のモデルのデータがどんどん更新されていくと思いますが、その際の ダイアログのキャンセル処理ってどうすれば良いのでしょうか? ・「キャンセル」ボタンが押された際に既にモデルが変更されているので、その際はバックアップ から戻すしかな? ・実際の設定データを持つクラスの情報と、ViewModelを別に設計する。 ・毎回ModelViewを作成、毎回コンストラクタを呼び出し、毎回設定ファイルから読み込む。 みたいな感じですかね? 調子に乗ってたくさん質問して申し訳ありません。以前から、この問題に頭を悩ましておりまして。 お答えして頂ける範疇で結構です。 よろしくお願いします。
toydev

2018/06/29 16:38 編集

コメントにはソースコード書きづらくて、悩んでいた時に本文書き換えを思い付きました! 設定画面のところやっぱり悩みますよね。 私も実装当時は悩んで、今は、juntaroさんが上げている候補のうちの2番目 ・実際の設定データを持つクラスの情報と、ViewModelを別に設計する。 に該当する方法を採用しています。 設定画面にはシングルトンとは別の ViewModel を実装し、設定画面表示時にシングルトンから値を読み込み、確定時にシングルトンに反映するという処理を個別に書いています。 シングルトン側の ViewModel は保存を意識した構造(Json.NET で読み書きしている)、設定画面側の ViewModel は画面のタブ分けを意識した構造として組んでいます。 設定画面とは別に、プルダウンメニューや各画面でのUI操作による直接設定は、シングルトンを直接バインド(もしくは設定値の変更により計算がいる部分は ReactiveProperty の Subscribe で PropertyChanged の監視)してリアルタイム反映されるようにしています。 「キャンセルしたら戻す」ではなく「確定したら反映する」の発想です。 今は設定画面のタブ毎に固有の ViewModel を実装し、シングルトンとの項目単位の値の読み書きを実装しているんですが、改めて整理してみると ViewModel は1つのクラスを共有する形で、値をコピーする汎用的な方法を用意さえすればもっと簡潔にできそうですねぇ…(白目)
juntaro

2018/07/01 01:44

toydevさん、ご親切に本当にありがとうございます。 MVVMの本質的な箇所が理解できず、悶々と悩んでおりましたが、少し理解できたような気がします。 --------------------------------------------------------------------------------------------- 設定画面にはシングルトンとは別の ViewModel を実装し、設定画面表示時にシングルトンから値を読み込み、確定時にシングルトンに反映するという処理を個別に書いています。 --------------------------------------------------------------------------------------------- 現状はモデルのインスタンスを作成した後、ディープコピーしてViewModelに渡し、 「確定したら反映する」を実現しています。 上記の方法と状況によって使い分けたいと思います。 上記の方法でいくと、シングルトンにINotifyPropertyChangedを実装することで、リアルタイムに反映という形ですね。 最後の「今は設定画面のタブ毎に・・・」のご説明も役に立ちました。ありがとうございます。
toydev

2018/07/01 14:43

伝わったようでよかったです。改良も入り教えたことより前進しているところも素晴らしい。 ディープコピーの実現をどうやったか参考までに教えて欲しいですー!
juntaro

2018/07/01 15:02

一度、自分のサンプルプログラムを貼り付けて送信する直前までいきましたが、よくよく考えると元々のサイトのパクリなので、元々のサイトの方を上げさせて貰います。 http://n2-csharp.blogspot.com/2009/09/blog-post_15.html 上記の方法を採用させて貰いました。 簡単にディープコピーが実現できて非常に便利です。
toydev

2018/07/01 23:20

ありがとうございます!
guest

0

Model ー ViewModel1 ー View1
└ーー ViewModel2 ー View2

View1 で値を入力したらViewModl1 からModelの値を変更。
Modelは値の変更を通知。
ViewModel2はModelを監視して、Modelの値変更の通知を受け取り。
通知を受け取ったらModelの値をViewModel2が取りに行ってView2に値を反映。

投稿2018/08/02 16:12

iti

総合スコア12

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

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

juntaro

2018/08/10 02:06

ありがとうございます。 全体のイメージはつかめたような気がします。 皆さんのご厚意に感謝しております。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問