Adding INotifyPropertyChanged to Model?

…衆ロ難τιáo~ 提交于 2019-11-29 10:35:40

Option1.
Separate entities, which being transferred between client and server (DTO), from entities, which are models on the client side. Implement INPC in models. Use mapping between these entities.

Option2.
Bind view to view model properties only. Make view model properties, which wrap corresponding model properties.

Option 3.
Is a mix of first two options. Do not aggregate model in view model. Use mapping between model and view model. Make view model properties, which correspond to model properties.

Well your approach is simply not the best. Much better would be to use a VM like this


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(...);
    }
  }
  ...
}

This would stick to the spirit of MVVM.

If you want your UI to notice when your model property changed, your model class MUST implement INotifyPropertyChanged and similar MVVM interfaces (IDataErrorInfo, etc...) in order to Notify to the UI that the property changed.

That's because you are not always updating your model from the the viewmodel, where you must implement INotifyProperyChanged and notify for changes.

Wrapping corresponding model properties in the viewmodel used when you cannot implement INotifyPropertyChanged in the model class, which makes the viewmodel to grow VERY fast and creates unnecessary code duplication.

Scenario for example:

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.
   }
}

Solution:

Implement INotifyPropertyChanged in you model class, create backing fields to your properties, and for each property setter, AFTER the set operation, raise OnPropertyChanged invoked method with the property name.

If you don't like to clutter your model with INotifyPropertyChanged code you could try using a NUGet package called PropertyChanged.Fody

You can use it like this;

using PropertyChanged;

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

Any public property in this class will now support INotifyPropertyChanged

I think you are on the right track. In the server side, you do not need INotifyPropertyChanged, thus do not add it to the domain classes in the server side.

You may just add some build symbols such as "WPF" to your client projects; and in the code first definitions implement INotifyPropertyChanged only if there is "WPF" build symbol. Then just add your server side domain classes as links to your presentation application. Something like;

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

....
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!