7

wpf MVVM (Prism based) アプリケーションでいくつかの設計上の質問に直面しています。アドバイスをいただければ幸いです。私のモデルは非常に単純です。

public class Customer
{
   public string FirstName {get;set;}
   public string LastName {get;set;}
}

ご覧のとおり、Model クラスの INotifyPropertyChnaged サポートはありません。INotifyPropertyChanged をサポートする CustomerDetails 画面用の ViewModel もあります。

public class CustomerDetailsViewModel:INotifyPropertyChanged /*Or NotificationObject*/
{
   /*INotifyPropertyChanged event */
   private Customer item;
   public Customer Item
   {
      get{return item;}
      set
      {
         item=value; 
         //Raise PropertyChanged
         //Set IsDirty to true
      }
   }
}

私の見解では、Item.FirstName へのバインディングと ViewModel の更新を使用しています。私の問題は - FirstName プロパティのみがビューを介して更新されており、モデル自体が INotifyPropertyChanged をサポートしていないため、Item セッターが呼び出されず、IsDirty は false のままです (したがって、IsDirty 通知は更新されません)。 UI)。

モデルで INotifyPropertyChanged をサポートし、ビュー モデルで Item.PropertyChanged イベントに登録し、実際に IsDirty を true に設定できることはわかっていますが、CodeFirst も使用していて、Model クラスが ServerSide 間で共有されているためです。クライアント側 (サービス参照の追加を使用しない) では、サーバー側に INotifyPreoprtyChanged のものを追加したくありません。

T4 テンプレートを使用してすべてのエンティティを (Customer として) 1 つずつコピーし、すべてのモデルに INotifyPropertyChanged サポートを追加する新しいプロジェクトを作成することを検討しています。それは合理的に見えるものですか?他の提案はありますか?

ありがとう!

4

5 に答える 5

4

オプション1。
クライアントとサーバー (DTO) の間で転送されるエンティティを、クライアント側のモデルであるエンティティから分離します。モデルで実装INPCします。これらのエンティティ間のマッピングを使用します。

オプション 2。
ビューをバインドして、モデル プロパティのみを表示します。対応するモデル プロパティをラップするビュー モデル プロパティを作成します。

オプション 3.
最初の 2 つのオプションを組み合わせたものです。モデルをビュー モデルに集約しないでください。モデルとビュー モデル間のマッピングを使用します。モデル プロパティに対応するビュー モデル プロパティを作成します。

于 2013-02-14T07:47:56.477 に答える
1

モデルプロパティが変更されたときに UI に通知する場合は、UIに.INotifyPropertyChangedIDataErrorInfoNotifyproperty changed

INotifyProperyChangedこれは、変更を実装して通知する必要があるビューモデルからモデルを常に更新しているわけではないためです。

モデルクラスに実装できない場合に使用されるビューモデルに対応するモデルプロパティをラップすると、ビューINotifyPropertyChangedモデルが非常に速く成長し、不要なコードの重複が作成されます。

シナリオの例:

public class Customer
{
   public string FirstName {get;set;}
   public string LastName {get;set;}

   // Changes the first name.
   public void ChangeFirstName(string newName)
   {
      FirstName = newName;
      //The UI will never know that the property changed, and it won't update.
   }
}

解決:

INotifyPropertyChangedモデルクラスに実装し、 に作成backing fieldsし、properties各プロパティsetterについて、set操作の後OnPropertyChanged、名前で呼び出されたメソッドを発生させpropertyます。

于 2015-02-27T15:44:18.767 に答える
1

あなたのアプローチは単に最善ではありません。このようなVMを使用する方がはるかに良いでしょう


public class CustomerDetailsViewModel : INotifyPropertyChanged
{
  public CustomerDetailsViewModel(Customer customer)
  {
    _item = customer;
  }
  private Customer _item;

  public string FirstName
  { 
    get { return _item != null ? _item.FirstName : null; }
    set 
    {
      if (_item == null)
        _item = new Customer(); // just an example, probably it's not the desired behavior
      _item.FirstName = value;
      RaisePropertyChanged(...);
    }
  }
  ...
}

これはMVVMの精神に固執します。

于 2013-02-14T07:52:32.173 に答える
0

モデルを INotifyPropertyChanged コードで乱雑にしたくない場合は、PropertyChanged.Fody という NUGet パッケージを使用してみてください。

このように使用できます。

using PropertyChanged;

[ImplementPropertyChanged]
public class Customer
{
   public string FirstName {get;set;}
   public string LastName {get;set;}
}

このクラスのパブリック プロパティは INotifyPropertyChanged をサポートするようになりました

于 2016-11-04T16:27:36.937 に答える
-1

あなたは正しい方向に進んでいると思います。サーバー側では必要ないためINotifyPropertyChanged、サーバー側のドメインクラスに追加しないでください。

「WPF」などのビルドシンボルをクライアントプロジェクトに追加するだけです。コードでは、最初の定義INotifyPropertyChangedは「WPF」ビルドシンボルがある場合にのみ実装されます。次に、サーバー側のドメインクラスをプレゼンテーションアプリケーションへのリンクとして追加します。何かのようなもの;

#if WPF
public class MyEntity : INotifyPropertyChanged
#else
public class MyEntity

....
于 2013-02-14T07:50:55.473 に答える