5

私は WPF/MVVM が初めてで、私が見つけた例は私が直面している問題をカバーしていないようです。

かなり複雑なビジネス構成オブジェクトを管理するための画面があります。MVVMでは、これは次のものが必要であることを意味すると思います:

  1. ゼロに近いロジックを持つ XAML ビュー
  2. 画面ロジックを持つ ViewModel クラス
  3. 私の通常のビジネス クラスはモデルの役割を果たし、すべてのビジネス ロジックを備えています。

私の状況では、ビジネス クラスの fieldA を変更すると、fieldB の値を変更したり、サブオブジェクトのリスト全体を入力したりするなど、さまざまな副作用が生じる可能性があるというビジネス ルールがあります。

私は間違っているかもしれませんが、これらのルールは実際には画面に関するものではなく、エンティティに関するものであるため、これらのルールをビジネス クラスにカプセル化しておく必要があると思います。

当然、これらの副作用はすぐに画面に戻る必要があります。

したがって、ユーザーの観点からは、fieldA を編集すると、View で更新された fieldB が表示される場合があります。

View から ViewModel にデータバインドする方法を理解しています。

しかし、私の場合、データバインディングの 2 つの層が必要なようです。1 つは View と ViewModel の間、もう 1 つは ViewModel と Model の間です。

基本的に同じ問題が 2 回発生したことを考えると、1 つの解決策を適用する必要があると思います。そのため、Model クラスを DependencyObject にし、そのプロパティを DependencyProperties にしました。

たとえば、fieldA を見ると、3 つのレイヤーすべてに表示されます。

  1. ViewModel.FieldA にデータバインドされたビジュアル コンポーネントとして表示します。例: text="{Binding FieldA, Mode=TwoWay}"
  2. ビューに「上向き」にバインドされ、モデルに「下向き」にバインドされた DependencyProperty としての ViewModel
  3. DependencyProperty としてモデル化する

パート 2 をスキップして View XAML をビジネス オブジェクトに直接結合することは避けたいと思います。これは、パターンのクリーンなアプリケーションとは思えません。おそらくそれは見当違いです。

基本的に、ViewModel に「パススルー DependencyProperty」が必要なようです。

私の質問:

  • これは正しい一般的なアプローチですか、それとも私はそれについてすべて間違っていると考えていますか?
  • このパススルー アプローチを使用した例はありますか?
  • ViewModel と Model FieldA DependencyProperties の間のパススルー バインディングを作成する適切な方法のコード例を教えてください。
4

3 に答える 3

1

私自身、この問題に苦労しましたが、MVVM に関しては非常によくある問題だと思います。私の答えは、ビューモデルを使用することの有効性を多少否定するため、ドメインを汚染しDependencyObjectないようにすることでした。INotifyPropertyChanged

ViewModel の目的は、特定のビューに関連する方法でモデルを公開することです。VM が本質的にドメイン オブジェクト全体を公開する必要がある場合、混乱します。これらを「エディター」ビュー モデルと呼びます。これらは、ドメイン オブジェクトからプロパティを渡すのが最も魅力的です。このような場合、VM にドメイン オブジェクト (コンポジション) への参照を与え、ゲッターとセッターを通過させます。ViewModelは、UI が検証エラーを更新または表示する必要がある場合に UI に通知するのではなく、INotifyPropertyChangedand を採用します。ドメインで検証エラーが発生した場合、VM はそれをキャッチし、ビューのデータ エラー情報の詳細に準備します。IDataErrorInfoDependencyProperty

于 2012-11-26T22:10:29.620 に答える
0

まず、ビュー モデルまたはモデルに依存関係プロパティ (DP) を使用することはお勧めしません。DataContextDP は、優先ルール、サポート、既定値など、UI の概念を念頭に置いて設計されたプロパティです。ビュー モデル内ではこれらの概念は必要ないため、INotifyPropertyChanged代わりに使用する必要があります。

モデルレイヤーへの単なるパススルーであるビューモデルを使用しても、まったく価値がありません。だからやらないで!レイヤー、構造、または概念をコードに追加する必要はありません。シンプルさは、常に努力すべきものです。

したがって、モデルレイヤーを実装できる場合は、INotifyPropertyChangedそれをビューにバインドするだけです。

ただし...場合によってINotifyPropertyChangedは、モデルに実装できない場合があります。たとえば、Web サービスから生成される場合があります。この場合、パススルー機能を実行するだけでなく、 を介して変更通知を追加するビュー モデルが必要になりますINotifyPropertyChanged

于 2012-11-27T06:25:22.510 に答える
0

DependencyObjectモデル/ドメイン クラスでandを使用することは避けるべきDependencyPropertyであり、ビュー モデル クラスはバインディングの目的でINotifyPropertyChangedandを採用する必要があるという Steve の意見に同意します。IDataErrorInfo

あなたのビュー モデル クラスではDependencyPropertyDataTriggers.

モデル レイヤー クラス内でトリガーされた変更を処理するために、ビュー モデル クラスのモデル/ドメイン オブジェクトへの参照も取得し、Steve が述べたようにゲッターとセッターをモデル/ドメイン クラスに渡します。モデル/ドメインクラスは、ビューモデルクラスがサブスクライブする必要があるイベントを発生させる必要があることを付け加えます。これによりOnPropertyChanged()、ビジネスで発生した変更に基づいてビューモデルクラスで1つ以上のプロパティを呼び出すことができます論理。

于 2012-11-27T02:52:12.197 に答える