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

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

ただいまの
回答率

90.51%

  • WPF

    693questions

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

  • MVVM

    76questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 436

juntaro

score 4

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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

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

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

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

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

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

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

  • リソース定義(XxxConfig.Instance アクセサでシングルトンが参照できる前提)
<ObjectDataProvider x:Key="XxxConfig" ObjectInstance="{x:Static Member=local:XxxConfig.Instance}" />
  • リソースの参照個所 Binding
<ComboBox SelectedValue="{Binding Source={StaticResource XxxConfig}, Path=ConfigProperty1}">
  <!-- ... -->
</ComboBox>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/25 14:41

    ありがとうございます。
    共通のViewModelそのものを個別画面のViewModelから参照するということですね。
    そして、そのままBindingする方向でシステム構築したいと思います。

    ご指示頂きましたリンクを見させて頂きました。
    既にシステムはLivetでの構築がすすんでおります。
    Prismにしておいた方が良かったかと思いつつも、当面はLivetを採用しようと思います。

    適切なご指示ありがとうございました。

    キャンセル

  • 2018/06/25 22:52 編集

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

    キャンセル

  • 2018/06/29 14:57

    ありがとうございます。
    本文に追記書きってできるんですね。初めて知りました。

    こういったシングルトンのモデルを使用して、ダイアログ等で設定メニューを作成した場合、
    バインディング元のモデルのデータがどんどん更新されていくと思いますが、その際の
    ダイアログのキャンセル処理ってどうすれば良いのでしょうか?

    ・「キャンセル」ボタンが押された際に既にモデルが変更されているので、その際はバックアップ
    から戻すしかな?
    ・実際の設定データを持つクラスの情報と、ViewModelを別に設計する。
    ・毎回ModelViewを作成、毎回コンストラクタを呼び出し、毎回設定ファイルから読み込む。

    みたいな感じですかね?
    調子に乗ってたくさん質問して申し訳ありません。以前から、この問題に頭を悩ましておりまして。
    お答えして頂ける範疇で結構です。
    よろしくお願いします。

    キャンセル

  • 2018/06/30 01:34 編集

    コメントにはソースコード書きづらくて、悩んでいた時に本文書き換えを思い付きました!

    設定画面のところやっぱり悩みますよね。
    私も実装当時は悩んで、今は、juntaroさんが上げている候補のうちの2番目
    ・実際の設定データを持つクラスの情報と、ViewModelを別に設計する。
    に該当する方法を採用しています。

    設定画面にはシングルトンとは別の ViewModel を実装し、設定画面表示時にシングルトンから値を読み込み、確定時にシングルトンに反映するという処理を個別に書いています。
    シングルトン側の ViewModel は保存を意識した構造(Json.NET で読み書きしている)、設定画面側の ViewModel は画面のタブ分けを意識した構造として組んでいます。
    設定画面とは別に、プルダウンメニューや各画面でのUI操作による直接設定は、シングルトンを直接バインド(もしくは設定値の変更により計算がいる部分は ReactiveProperty の Subscribe で PropertyChanged の監視)してリアルタイム反映されるようにしています。

    「キャンセルしたら戻す」ではなく「確定したら反映する」の発想です。

    今は設定画面のタブ毎に固有の ViewModel を実装し、シングルトンとの項目単位の値の読み書きを実装しているんですが、改めて整理してみると ViewModel は1つのクラスを共有する形で、値をコピーする汎用的な方法を用意さえすればもっと簡潔にできそうですねぇ…(白目)

    キャンセル

  • 2018/07/01 10:44

    toydevさん、ご親切に本当にありがとうございます。
    MVVMの本質的な箇所が理解できず、悶々と悩んでおりましたが、少し理解できたような気がします。

    ---------------------------------------------------------------------------------------------
    設定画面にはシングルトンとは別の ViewModel を実装し、設定画面表示時にシングルトンから値を読み込み、確定時にシングルトンに反映するという処理を個別に書いています。
    ---------------------------------------------------------------------------------------------
    現状はモデルのインスタンスを作成した後、ディープコピーしてViewModelに渡し、
    「確定したら反映する」を実現しています。
    上記の方法と状況によって使い分けたいと思います。

    上記の方法でいくと、シングルトンにINotifyPropertyChangedを実装することで、リアルタイムに反映という形ですね。
    最後の「今は設定画面のタブ毎に・・・」のご説明も役に立ちました。ありがとうございます。

    キャンセル

  • 2018/07/01 23:43

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

    キャンセル

  • 2018/07/02 00:02

    一度、自分のサンプルプログラムを貼り付けて送信する直前までいきましたが、よくよく考えると元々のサイトのパクリなので、元々のサイトの方を上げさせて貰います。
    http://n2-csharp.blogspot.com/2009/09/blog-post_15.html

    上記の方法を採用させて貰いました。
    簡単にディープコピーが実現できて非常に便利です。

    キャンセル

  • 2018/07/02 08:20

    ありがとうございます!

    キャンセル

0

Model ー ViewModel1 ー View1
└ーー ViewModel2 ー View2

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/10 11:06

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

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • WPF

    693questions

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

  • MVVM

    76questions

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