2010-12-30 8 views
2

はここMVVM WPF/SLの開発標的にシナリオの例です:MVVMパターンでWPFおよびSLの変更通知伝播を実装するにはどうすればよいですか?

  • ビューデータはモデルプロパティ 「ターゲット」を表示するバインドを
  • 「ターゲット」は、「データ」と呼ばれるオブジェクトのフィールドを公開しています「Original」が変更されたときにローカルモデル「Original」にある
  • が存在する場合は、通知モデルをビューモデルに通知し、その変更通知をビューに伝播する必要があります。

ここに私が思いついた解決策がありますが、私はそれほど多くを好きではありません。私は他のアイデアを探しています。私たちは何か堅実なものを思いつきます。マイクロソフトは、MVVM開発のためのより良いツールのためにWPF/SL拡張で.NET 5をリリースする予定です。

ここで問題は、「この問題を解決するために何をしましたか、それがどのようにあなたのために働いたのですか?

オプション1.提案

は、それがその気にプロパティの文字列値を監視データのPropertyChangedイベントにハンドラをアタッチが変わったかもしれない、と昇給適切な通知。

なぜ私はそれを好きではない:新しいソースへのデータの変更は、イベントが登録/国連登録されなければならない場合

変更は、バブルは当然、オブジェクトを明示的に、注目されている必要がありません。

のはなぜな種類のそれのように:

私は変更のプロパゲーションを明示的に制御を取得し、私はそのような依存性などのアプリケーションのより高いレベルで属している任意の種類を使用する必要はありません。

オプション2

提案:

nameプロパティ名を使用して、すべてのプロパティ間でイベントを再度発生させPropertyChangedイベントは、のデータにハンドラーを接続します。

なぜ私はそれを好きではない:

は、これは本質的にオプション1と同じですが、あまりインテリジェントな、と彼らは同じでなければならないとして、私のプロパティ名を変更することはありませんし、私を強制的にデータなぜな種類のそれのような

のプロパティ名:

それはセットアップが非常に簡単だと私はそれについて考える必要はありません...その後、再び、私は考えるようにしようとした場合、名前を物に変更する私は自分の足で撃って、それから考えなければならない!

オプション3

提案:

は依存オブジェクトから私のビューモデルを継承し、直接変更の結合源を通知します。私はそれを好きではないのはなぜ

は:

を私も依存プロパティ/オブジェクトは、これを行うことができ、100%わからないんだけど、に見てちょうど考えられていました。また、私は個人的に、DepobのようなWPF/SL型がビューモデルレベルに属しているとは感じていません。

I種類のそれのような理由:それは私が求めてい機能がある場合

が、それは良い答えです!それは厄介なレイヤリングの問題です。

オプション4.

提案:

は、リンクされたパイプラインを通じて、すべてをpropogateするタスクのParallelsデータフロー図書館のオフに基づいて一貫したエージェントのメッセージングシステムを使用してください。

なぜ私はそれを好きではない:

私はこれを試したことがない、と何とか私はそれが欠けていることになると思い、プラスそれはすべての方法の周りに完全に異なった私のコードについて考えるために私を必要とします。

なぜな種類のそれのように:

それは私がプッシュベースのデータモデルといくつかの非常に楽しい操作を行うにできるようにして、個人ビューモデルのプロパティを変更するには、検証とセッターとしてActionBlocksを使用しての可能性について持っていますPropertyChanged通知を明示的に制御します。

答えて

1

私は基本的にオプション4を使用しています。アプリケーションの状態が変更されたとき(したがって、モデルのデータが変更されたとき)、MVVM FoundationMessengerを使用して通知を送信します。このデータをデータバインディングに必要とするViewModelは、このメッセージを購読し、それに応じてローカルプロパティを更新し、変更が発生したことをバインディングシステムに通知するためにRaisePropertyChanged() *を呼び出すことができます。

はい、これはさまざまなことを考える方法ですが、その価値はあると思います。 ViewModelは非常に緩やかに結合されています。アプリケーションのモデルやサポートしているビューには依存しません。

私が気づいた最大の欠点は、Messengerを大量に使用するデバッグコードが難しいことです。基本的に、例外がスローされると、実際の違反コードではなく、Messengerクラスのメソッドが呼び出されます。これは、Messengerが弱い参照を利用しているからです。あなたはこの問題を回避する方法を学びますが、それは間違いなく理想的です。

私が取り組んでいた最近のアプリケーションでは、アプリケーションデータに対するすべての変更をAppDataManagerと呼ばれる1つの大きくてシンプルなクラスに集中させることに決めました。このクラスには、変更が必要なすべてのデータのフィールドがあります。起動時に初期化された後、データ変更は常に、またはほとんど常にユーザーによって開始されます。双方向データバインディングのおかげで、ユーザーアクションはViewModelのプロパティに変更をもたらします。この変更はメッセージを使用してAppDataManagerに転送されます。 AppDataManagerは、このデータへの参照を変更し、このデータが変更されたことを関心のあるViewModelsに通知するメッセージを送信します。私は通常、変更されたデータをメッセージに含めます(受信者がデータを見つける場所を知る必要はありません)。私はこれが最高のアーキテクチャであるとは確信していません。大規模なアプリケーションではどのように拡張されるのかわかりませんが、これまでのところうまくいきました。明らかに、集中化に対する別のアプローチは、ViewModelが互いにメッセージに直接サブスクライブするネットワークアプローチであることは明らかである。これはうまくいくかもしれませんが、試していません。私は、データへのすべての変更が1つのクラスを介してルーティングされた場合、元に戻すシステムをもっと簡単に実装できることを発見しました。私のデータも階層的に配置されていたので、階層の最上部の変更は「葉」までカスケードする必要があります(たとえば、マップを変更した場合は道路を変更しなければなりません。道路を構成するウェイポイントを変更する)。私は、これを行うために任意のViewModelを選択するよりも、このカスケードを一元的に管理するほうがはるかに簡単だとわかりました。

* RaisePropertyChangedは、MVVM Foundationの一部であるObservableObjectのメンバーです。私のプロジェクトのすべてのViewModelはObservableObjectから継承されています。

注:私はMVVM Foundationからさらに進化していると思われるMVVM Light ToolkitにMVVM Foundationから切り替えることを考えています。

+0

あなたのモデルから興味のある人にメッセージを送信していますか? –

+0

@chibacity、yes。 – devuxer

+0

@ダンそれで本質的にモデルはメッセージビューをすることができます。それはMVVMレイヤーを破壊します。 –

関連する問題