170

私が試したほとんどのMVVMの例では、Modelが実装され ていますINotifyPropertyChangedが、Josh SmithのCommandSinkの例 では、ViewModelが実装されてINotifyPropertyChangedいます。

私はまだMVVMの概念を認知的にまとめているので、次のことを理解していません。

  • 作業を開始INotifyPropertyChangedするには、ViewModelにを配置する必要がありますCommandSink
  • これは単なる規範の逸脱であり、実際には問題ではありません
  • 常にモデルを実装する必要があります。INotifyPropertyChangedこれは単なる間違いであり、コード例からアプリケーションに開発された場合に修正されます。

あなたが取り組んできたMVVMプロジェクトで他の人はどのような経験をしましたか?

4

17 に答える 17

154

モデルがを実装すべきではないという概念に強く反対しINotifyPropertyChangedます。このインターフェースはUI固有ではありません!単に変更を通知するだけです。実際、WPFはこれを頻繁に使用して変更を識別しますが、それがUIインターフェイスであることを意味するわけではありません。私はそれを次のコメントと比較します:「タイヤは車の付属品です」。確かにそうですが、自転車やバスなども使っています。要約すると、そのインターフェイスをUIのものと見なさないでください。

そうは言っても、それは必ずしもモデルが通知を提供するべきだと私が信じているという意味ではありません。実際、経験則として、モデルは、必要でない限り、このインターフェースを実装すべきではありません。サーバーデータがクライアントアプリにプッシュされないほとんどの場合、モデルは古くなっている可能性があります。しかし、金融市場のデータを聞いていると、モデルがインターフェイスを実装できない理由がわかりません。例として、特定の値の買値または売値を受け取ったときにアラートを発行したり(電子メールを介して)注文したりするサービスなど、UI以外のロジックがある場合はどうなりますか?これは、可能なクリーンな解決策である可能性があります。

ただし、物事を達成する方法はいくつかありますが、私は常に単純さを支持し、冗長性を回避することを主張します。

何が良いですか?コレクションのイベントまたはビューモデルのプロパティの変更を定義し、それをモデルに伝播するか、ビューに(ビューモデルを介して)本質的にモデルを更新させますか?

誰かが「これはできない、または」と主張しているのを見ると、それは彼らが何について話しているのかわからないという兆候です。

それは本当にあなたのケースに依存します、そして実際、MVVMは多くの問題を抱えたフレームワークであり、私はまだ全面的にMVVMの一般的な実装を見ていません。

MVVMの多くのフレーバーと、一般的な問題のいくつかの解決策を説明する時間がもっとあればいいのにと思います。ほとんどは他の開発者によって提供されていますが、別の機会に説明する必要があると思います。

于 2010-05-10T16:49:13.593 に答える
112

まったく逆だと思いますが、私は常にINotifyPropertyChangedViewModelを使用しています。たとえば、ViewModelに配置する必要があるなど、かなりWPF固有の機能でモデルを汚染したくない場合がありますINotifyPropertyChanged

他の人は同意しないと思いますが、それが私の仕事のやり方です。

于 2009-04-21T12:09:11.657 に答える
30

MV-VMでは、ViewModelは常に(モデルは常にではない)を実装しますINotifyPropertyChanged

http://blogs.msdn.com/llobo/archive/2009/05/01/download-mv-vm-project-template-toolkit.aspxからMV-VMプロジェクトテンプレート/ツールキットを確認してください。これはDelegateCommandコマンド用にを使用し、MV-VMプロジェクトの開始テンプレートとして最適です。

于 2009-05-04T12:35:05.513 に答える
13

MVVMの名前は非常に貧弱で、ViewModelをViewModelと呼ぶと、多くの人が、誰が触れようとしてもデータを制御するDataControllerである、適切に設計されたアーキテクチャの重要な機能を見逃していると思います。

ビューモデルをより多くのDataControllerと見なし、DataControllerがデータにアクセスする唯一のアイテムであるアーキテクチャを実装する場合、データに直接アクセスすることはなく、常にDataControllerを使用します。DataControllerはUIに役立ちますが、必ずしもUIだけに役立つわけではありません。ビジネスレイヤー、UIレイヤーなどに使用します。

DataModel -------- DataController ------ View
                  /
Business --------/

あなたはこのようなモデルになってしまいます。ビジネスでさえ、ViewModelを使用してデータに触れるだけで済みます。そうすれば、あなたの難問は消え去ります。

于 2011-01-01T16:46:24.810 に答える
9

モデルをどのように実装したかによって異なります。私の会社は、LhotkaのCSLAオブジェクトと同様のビジネスオブジェクトを使用しINotifyPropertyChangedており、ビジネスモデル全体で広範囲に使用しています。

私たちの検証エンジンは、このメカニズムによってプロパティが変更されるという通知に大きく依存しており、非常にうまく機能します。明らかに、変更の通知が操作にとってそれほど重要ではないビジネスオブジェクト以外の別の実装を使用している場合は、ビジネスモデルの変更を検出するための他の方法がある可能性があります。

必要に応じてモデルからの変更を伝播するビューモデルもありますが、ビューモデル自体は基になるモデルの変更をリッスンしています。

于 2009-04-21T12:55:52.077 に答える
8

私はPauloの答えに同意しますINotifyPropertyChanged。モデルでの実装は完全に受け入れられ、Microsoftによって提案されています-

通常、モデルは、ビューへのバインドを容易にする機能を実装します。これは通常、INotifyPropertyChangedおよび INotifyCollectionChangedインターフェイスを介したプロパティおよびコレクションの変更通知をサポートすることを意味します。ObservableCollection<T>オブジェクトのコレクションを表すモデルクラスは、通常、インターフェイスの実装を提供するクラス から派生し INotifyCollectionChangedます。

そのタイプの実装が必要かどうかを決めるのはあなた次第ですが、覚えておいてください-

モデルクラスが必要なインターフェイスを実装していない場合はどうなりますか?

INotifyPropertyChanged、、、、またはインターフェイスINotifyCollectionChangedを 実装していないモデルオブジェクトを操作する必要がある場合があります。このような場合、ビューモデルはモデルオブジェクトをラップし、必要なプロパティをビューに公開する必要があります。これらのプロパティの値は、モデルオブジェクトによって直接提供されます。ビューモデルは、ビューがそれらに簡単にデータバインドできるように、公開するプロパティに必要なインターフェイスを実装します。IDataErrorInfoINotifyDataErrorInfo

取得元-http://msdn.microsoft.com/en-us/library/gg405484( PandP.40 ).aspx

私はモデルに実装していないいくつかのプロジェクトで働いてきましたが、INotifyPropertyChangedこれが原因で多くの問題に直面しました。VMではプロパティの不要な複製が必要でしたが、同時に、BL / DLに渡す前に、基になるオブジェクトを(更新された値で)更新する必要がありました。

モデルオブジェクトのコレクション(編集可能なグリッドやリストなど)や複雑なモデルを操作する必要がある場合は、特に問題が発生します。モデルオブジェクトは自動的に更新されないため、VMですべてを管理する必要があります。

于 2015-12-15T09:06:50.947 に答える
4

それはすべてユースケースに依存すると思います。

プロパティがたくさんある単純なモデルがある場合は、INPCを実装することができます。簡単に言うと、このモデルはPOCOのように見えます。

モデルがより複雑で、インタラクティブなモデルドメイン(モデルを参照し、他のモデルのイベントをサブスクライブするモデル)に存在する場合、モデルイベントをINPCとして実装することは悪夢です。

他のモデルと連携しなければならないモデルエンティティの立場に身を置いてください。購読するさまざまなイベントがあります。それらはすべてINPCとして実装されています。あなたが持っているそれらのイベントハンドラーを想像してみてください。if節および/またはswitch節の1つの巨大なカスケード。

INPCに関する別の問題。実装ではなく抽象化に依存するようにアプリを設計する必要があります。これは通常、インターフェイスを使用して行われます。

同じ抽象化の2つの異なる実装を見てみましょう。

public class ConnectionStateChangedEventArgs : EventArgs
{
    public bool IsConnected {get;set;}
}

interface IConnectionManagerINPC : INotifyPropertyChanged
{
    string Name {get;}
    int ConnectionsLimit {get;}
    /*

    A few more properties

    */
    bool IsConnected {get;}
}

interface IConnectionManager
{
    string Name {get;}
    int ConnectionsLimit {get;}
    /*

    A few more properties

    */
    event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged;
    bool IsConnected {get;}
}

今、それらの両方を見てください。IConnectionManagerINPCは何を教えてくれますか?そのプロパティの一部が変更される可能性があります。あなたはそれらのどれかわからない。実際、IsConnectedのみが変更されるように設計されており、残りは読み取り専用です。

反対に、IConnectionManagerの意図は明確です。「IsConnectedプロパティの値が変更される可能性があることをお伝えできます」。

于 2013-02-19T08:09:03.157 に答える
3

私はあなたのViewModelで言うでしょう。モデルはUIに依存しないため、モデルの一部ではありません。モデルは「ビジネスにとらわれないものを除くすべて」である必要があります

于 2009-04-21T12:48:55.680 に答える
3

ただし、(このプレゼンテーションリンクテキストのように)モデルがサービスである場合があります。これは、アプリケーションにオンラインでデータを提供し、新しいデータが到着したか、イベントを使用してデータが変更されたという通知を実装する必要があります。

于 2009-11-10T14:07:02.633 に答える
3

MV-VMを守りたいのなら、答えはかなり明確だと思います。

参照: http: //msdn.microsoft.com/en-us/library/gg405484 (v = PandP.40).aspx

MVVMパターンでは、ビューはUIと任意のUIロジックをカプセル化し、ビューモデルはプレゼンテーションロジックと状態をカプセル化し、モデルはビジネスロジックとデータをカプセル化します。

「ビューは、データバインディング、コマンド、および変更通知イベントを介してビューモデルと対話します。ビューモデルは、モデルの更新をクエリ、監視、調整し、ビューに表示するために必要に応じてデータを変換、検証、および集約します。」

于 2013-08-24T06:46:42.893 に答える
2

モデルがViewModelで明確に公開されている場合は、モデルにINPCを実装することを使用できます。しかし、一般的に、モデルをラップするViewModelは、モデルの複雑さを軽減するための彼自身のクラスです(これはバインディングには役立ちません)。この場合、INPCはViewModelに実装する必要があります。

于 2019-04-05T16:40:46.930 に答える
1

INotifyPropertyChangeモデルでインターフェースを使用しています。実際には、モデルプロパティの変更は、UIまたは外部クライアントによってのみ実行される必要があります。

私はいくつかの長所と短所に気づきました:

利点

通知機能はビジネスモデルにあります

  1. ドメイン駆動によると、それは正しいです。いつ上げるか、いつ上げないかを決定する必要があります。

短所

モデルにはプロパティ(数量、レート、手数料、合計料金)があります。Totalfrieghtは、数量、レート、手数料の変更を使用して計算されます。

  1. dbから値をロードすると、合計frieght計算は3回呼び出されます(数量、レート、手数料)。それは一度でなければなりません。

  2. レート、数量がビジネスレイヤーで割り当てられている場合、通知機能が再度呼び出されます。

  3. おそらく基本クラスで、これを無効にするオプションがあるはずです。ただし、開発者はこれを行うのを忘れる可能性があります。

于 2011-09-20T17:49:51.263 に答える
1

INotifyPropertyChangeモデルではなく、ビューモデルでを使用するだけです。

モデルは通常IDataErrorInfo、検証エラーを処理するためにを使用するため、ViewModelを保持するだけで、MVVMの道を進んでいます。

于 2011-11-30T11:48:27.990 に答える
0

通常、ViewModelはを実装しINotifyPropertyChangedます。モデルは何でもかまいません(xmlファイル、データベース、さらにはオブジェクト)。モデルは、ビューに伝播するビューモデルにデータを提供するために使用されます。

ここを参照してください

于 2011-07-16T02:33:48.313 に答える
0

ビュー内のオブジェクトの参照が変更されたとします。正しい値を表示するために、すべてのプロパティを更新するように通知するにはどうすればよいですか?すべてのオブジェクトのプロパティをビューで呼び出すOnPropertyChangedことは、私の見解ではごみです。

したがって、私が行うことは、プロパティの値が変更されたときにオブジェクト自体に通知するようにすることです。私の見解では、などのバインディングを使用Object.Property1しますObject.Property2。このようにして、現在ビューに保持されているオブジェクトを変更したいだけの場合は、変更しますOnPropertyChanged("Object")

オブジェクトのロード中に何百もの通知を回避するために、ロード中にtrueに設定したプライベートブールインジケーターがあります。これは、オブジェクトからチェックされ、OnPropertyChanged何もしません。

于 2011-08-23T07:15:45.797 に答える
0

私は、ビューモデルが実装INotifyPropertyChangeし、モデルが別の「レベル」で通知を使用できると思います。

たとえば、一部のドキュメントサービスとドキュメントオブジェクトでは、ビューモデルがビューをクリアして再構築するためにリッスンするdocumentChangedイベントがあります。ビューモデルの編集では、ビューをサポートするためにドキュメントのプロパティのpropertychangeがあります。サービスが保存時にドキュメントで多くのことを行う場合(変更日、最後のユーザーなどの更新)、Ipropertychangedイベントの過負荷を簡単に取得し、documentchangedだけで十分です。

ただしINotifyPropertyChange、モデルで使用する場合は、ビューで直接サブスクライブするのではなく、ビューモデルで中継することをお勧めします。その場合、モデルでイベントが変更されたときに、ビューモデルを変更するだけで、ビューは変更されません。

于 2011-10-14T05:01:11.593 に答える
0

ビューにバインドされているすべてのプロパティは、ViewModelにあります。したがって、INotifyPropertyChangedインターフェイスを実装する必要があります。したがって、ビューはすべての変更を取得します。

[MVVM Lightツールキットを使用して、ViewModelBaseから継承させました。]

モデルはビジネスロジックを保持しますが、ビューとは何の関係もありません。したがって、INotifyPropertyChangedインターフェイスは必要ありません。

于 2019-02-28T13:27:32.997 に答える