4

モデルとビューモデルの関係を理解し​​ようとしていますが、同じ問題にぶつかり続けています。フィールドが 1 つだけの「Person」クラスがあるとします。

public class Person
{
   public string Name;
}

次のフェーズでは、Person を表示するユーザー コントロールを作成した XAML アーティストがいて、MVVM の慣例に従って、ビューを VMPerson (View-Model Person) に関連付ける必要があるため、別のクラスを追加します。

public class VMPerson : INotifyPropertyChange
{
   private Person person;

   public VMPerson():this(new Person()){}

   public VMPerson(Person person)
   {
      this.person = person;
   }

   public Name
   { get { return person.name; }
   { set { person.name = value; PropertyChange("Name"); }
}

これで、ほとんどすべてのセットアップが完了しました..しかし、VM クラスはモデル クラスの変更にどのように関連しますか?? INotifyPropertyChanged を追加し、モデルに「Name」のプロパティを追加すると、ViewModel クラスに非常によく似た、必要のない余分なレイヤーが作成されます。Model クラスをそのままにして、view-model クラスの内部の変更について通知を受ける方法はありますか? モデルに実装される INotifyPropertyChanged メカニズムまたは同様のものを使用する以外に方法がない場合、なぜ VM が必要なのですか?? ビューに提供される1つのクラスにいくつかの「モデル」クラスを集約する状況のためだけですか?

私が説明したことによると、ビューコードビハインドをコントローラーとして使用しているときにモデルからビューへのパターンがMVVMよりも優れた抽象化になると思われるため、理解に何かが欠けているに違いないと思いますが、それについては確かにわかりません. 誰かが私に欠けているものを説明できますか? ありがとう。

4

3 に答える 3

3

ビューモデルのコードをモデルに入れることは最善の考えではありません

多くの場合、viewmodels は、実際には何の価値も追加しない追加のコード層のように見えることから始まりますが、要点は、それらが進化できるということです。

モデルの役割がビジネス ロジックをカプセル化することであるのに対し、VM の役割はビューに利便性を提供することです。コードの機能が成長するにつれて、 はさらにリッチになります。ある時点で、コード サイズがモデルよりもはるかに大きくなる可能性さえあります。そのため、利便性とビジネス ロジックの部分が互いに適切に分離されるように区別が行われます。これは、コードの保守性に良い影響を与えます。INotifyPropertyChanged

ビューモデルのコードをビューに入れることは最善の考えではありません

ここでの理由は異なります。これを行った後、ビューモデルを別のタイプのビューで使用する必要がある場合は、すべてのロジックを他のビューの分離コードにも複製する必要があります。重複は良くありません。DRYがいいです。

MVVM の非常に重要な機能はテスト可能性を提供することであり、テスト可能性は少なくとも 2 種類のビュー (実際のビューとモック) を必然的に意味することを考慮すると、このアプローチの必要性は明らかです。

于 2012-05-11T11:43:44.587 に答える
1

私がそれを見る方法は次のとおりです:-ViewModel、これはある意味で古い MVP のプレゼンターに似ており、さまざまなビジネス機能 (IDealService や IStaticDataService の消費など) を含み、結合します。

私にとってのモデルは、単にデータを表す DataModel に非常に近いものです。

VM にデータ関連のビットが多すぎる場合は、通常、それらをモデルに移動し、VM からそのインスタンスを使用します。

つまり、次のことができます。

public class VMPerson : INotifyPropertyChange
{
   public Person PersonItem {get; set;}

   public VMPerson()
   {
      PersonItem = new Person();
   }
}

あなたはまだあなたの経由で人の名前に到達することができます: {Binding PersonItem.Name}

元の Person クラスが INPC を継承していない場合、通知可能にするのは難しいと思います。

于 2012-05-11T12:36:23.870 に答える
1

ビューモデルの目的の 1 つは、モデルからデータを取得し、データを視覚化する必要がある方法で処理することです。

たとえば、モデルに DateOfBirth という情報があり、実際の年齢を視覚化したいとします。

この場合、ViewModel で処理 (DateOfBirth を実際の年齢 (DateTime.Now.Year - DateOfBirth.Year など) に変換) を行う必要があります。

特定のケースでは、ViewModel はモデルからのデータの単なるラッパー (処理なし) であり、明らかに Viewmodel は必要ありません。

ViewModel でモデルの変更を取得するために (VM での処理を必要としないプロパティの場合)、通常はモデルにも INotifyPropertyChanged を実装します。これにより、ViewModel 内の多くのラッパー プロパティが回避されます。

私のViewModelには、次のようなものがあります

_model.PropertyChanged += PropertyChangedEventHandler(OnPropertyChangedModel);

void OnPropertyChangedModel(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    OnPropertyChanged(e.PropertyName);
}

この場合、モデル プロパティはビューに直接送信されることに注意してください (ViewModel での処理はありません)。

于 2012-05-11T11:59:42.797 に答える