2017-01-20 13 views
1

Iクラスを有し、A、B、C、DMVVM:のviewmodelsの緩く結合

Aは、EとBへとAViewModelこれらにおいてCおよびD

のリストへの参照が露出される有します木の中に

Aのビューは、画像のようになります。コレスポンデントビューを選択したノードが表示されるべき

enter image description here

たとえばEは、選択されたノードである:

は私の質問は、以下であるE、B、C及びD

ためのviewmodelsあります。私はそれをAViewModelに "SelectedItemオブジェクト"として格納します。 疎結合の方法でEViewModelを作成する最良の方法は何ですか。AViewModelでEViewModelを参照したくない場合があります。

アップデート:私は約ソリューションを考えていたが、私は他の場所にいることを見たことがない

たとえば、私は私のPOCOSを公開することができ(B、C、D、E)からAViewModel。そしてXAMLでは、ContentControlをこれらのオブジェクトに直接バインドできました。コンバータを使用すると、BなどにバインドするときにBViewModelを持つことができます。

+0

xamlを投稿して、ホイールを再開発する必要はありませんか? – lokusking

答えて

0

Aビューに「リスト」と選択したビューが表示されている場合は、AViewModelでEViewModelリファレンスを使用することは完全に受け入れられます。 ViewModelsは、ビューの「反映」であってもよい。したがって、AビューにEViewが含まれる場合、AViewModelにはEViewModelが含まれている場合があります。ビュー・モデルをネストするだけで、ビュー・レイヤーと同じツリーが作成されます。

AVfrontModelでは参照EまたはBはありませんが、参照のみEViewModel、BViewModel ... AViewリストにはモデルクラスが表示されず、ViewModelクラスが表示されます。 SelectedItemはViewModelとして型付けされ、 "Display"ビュー部分をSelectedItemに直接バインドできます。次に、ビューレイヤで適切なDataTemplateを使用して、対応するビューを表示できます。望むことができます

+0

これは私が現在やっていることです:)しかし、私はいつもこれがもっと良い方法でできると感じました。 – jannagy02

1

MVVMアプリケーションで疎結合の方法でビューモデルと他のコンポーネントとの間で通信する一般的で広く受け入れられている方法は、イベントアグリゲータまたはメッセンジャーを使用することです。詳細については、次のリンクを参照してください。https://msdn.microsoft.com/en-us/magazine/jj694937.aspx: - MVVMでメッセンジャーと表示サービスhttps://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/

MVVM:ビュー・モデルとの間で通信するために、イベント集約パターンを用い

。イベントアグリゲータ、メッセンジャーを使用してhttps://social.msdn.microsoft.com/Forums/en-US/22907a0f-d805-4195-8272-7c284b72d2ee/example-of-using-shared-services-prism?forum=wpf

または共有サービスを使用して、ビューモデルクラス間のすべての参照を削除することができますことを意味します

別のオプションは、あなたとビューモデルを注入共有サービスを使用することです。

各ビューモデルは、相互に強力な参照を持つビューモデルクラスの代わりに、単一のイベントアグリゲータ/メッセンジャー/共有サービスについてのみ認識し、このモデルとのみ通信します。ビューモデルAは、任意の数のメッセージを送信して、他のビューモデルがサブスクライブして内部的に受信して処理することができる。

は、私の質問はありません作成することなく、別のビューモデルのインスタンスを作成する疎結合のviewmodels

間の通信については、密結合を持たずにViewModelにのインスタンスを作成するのトピックに関するベストプラクティスをあります弦結合は不可能である。 1つのビューモデルが別のビューモデルのインスタンスを作成する場合、それらは定義によって強く結合されます。これを防ぐために、あなたは

public ViewModelB(IViewModelA viewModelA) 
{ 
    //... 
} 

はその後ViewModelBがインタフェース型の代わりに、ViewModelAの具体的な実装に依存して、他のビューモデルを実装し、例えば:あるインターフェイスタイプとビューモデルを注入できます。

public ViewModelB() 
{ 
    _viewModelA = new ViewModellA(); 
} 

しかし、あなたは本当にあなたのビューモデルクラス間の疎結合を心配している場合、あなた: - 上記のように - 強固に結合し、その後ViewModelAとViewModelBは常になりますので、それはこのような何かを行うよりも少しはましです直接参照を取り除き、イベントアグリゲータまたはメッセンジャーを使用してそれらの間でコミュニケートする必要があります。

+0

私の質問は、疎結合ViewModel間の通信ではなく、Thigtカップリングを持たないViewModelのインスタンスを作成するためのベストプラクティスについてです。 – jannagy02

+0

これは不可能です。 1つのビューモデルが別のビューモデルのインスタンスを作成する場合、それらは定義によって強く結合されます。詳細については私の編集された答えを見てください。 – mm8

+0

@ jannagy02ファクトリメソッドを使用し、インターフェイスのインスタンスを取得します。または、PrismのようなDIコンテナを使用します。タイプ(インターフェイスを使用する)を要求し、具体的なタイプを取得します。しかし、あなたがB、C、D、Eのように聞こえるのはすべてPOCO(独自のビューモデルでラップされているかもしれません)です。AViewModelは、データの形状、変換、提示の仕事がAViewModelには分かります。景色。 – slugster

関連する問題