question

DaljitSingh-1549 avatar image
1 Vote"
DaljitSingh-1549 asked ·

How to avoid proxy properties in a ViewModel to access properties of the Model in MVVM?

I have come accross this problem while developing my UWP application. It seems that the community advice to implement UWP app is to follow the MVVM pattern. So in my code I have a ViewModel like the following:

public class MyViewModel : ViewModelBase
{
    private Model _model;
    
    public MyViewModel()
    {
        this.Model = model;
    }
    public Model Model 
    {
        get; set;
    }
}


In this way I am able to access my Model from my view and simply bind properties like property={Binding Model.Property}. This works fine however when I change my property in the Model obviously the UI does not get updated. What I could do instead would be reimplement each property of Model in ViewModel (which implements INotifyPropertyChanged interface so each time a property is updated the UI is notified) through a proxy property like the following:

public ModelProperty
{
    get { return this.Model.Property; };
    private set;
}


Doing this would require a lot of effort (since my Model has a lot of properties) and I would just be duplicating my code. The alternative would to implement the INotifyPropertyChanged interface in my Model and then expose the model like above in my view model. However, this seems to against the paradigms of MVVM.

So my question is what is the best way to avoid the need of proxy properties in my ViewModel?

windows-uwp
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RichardZhang-MSFT avatar image
0 Votes"
RichardZhang-MSFT answered ·

Hello,​

Welcome to our Microsoft Q&A platform!

In UWP, if you need to bind the property to notify the UI when it changes, then inheriting the INotifyPropertyChanged interface is a necessary step.

It's just that there will be some changes in the way we write attributes. Your Model and _model properties are not related, you can try to write:

 public class MyViewModel : ViewModelBase
 {
     private Model _model;
     public Model Model
     {
         get => _model;
         set
         {
             _model = value;
             // OnPropertyChanged();
         }
     }
 }

The same wording can be used on specific properties of Model:

 public class Model : INotifyPropertyChanged
 {
    
     private string _property;
     public string Property
     {
         get => _property;
         set
         {
             _property = value;
             OnPropertyChanged();
         }
     }
    
     public event PropertyChangedEventHandler PropertyChanged;
     public void OnPropertyChanged([CallerMemberName]string propertyName = "")
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
 }

Thanks.

· 2 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi Richard, thanks for the answer. As I have already noted, my worries is that implementing INotifyPropertyChanged interface on the model itself seems to go against the best practices of MVVM pattern. Since a model should be just pure "data" in accordance with MVVM guidelines, so my follow up question is: Is this ok? Is this the best practice recommended by Microsoft when dealing with problem?

0 Votes 0 ·

Hi, Under ideal conditions, in MVVM, data and UI should be completely separated, but in actual development, please do not be limited to this. Any best practice is based on certain conditions, you need to adjust according to your development scenario.

2 Votes 2 ·
yanxiaodi avatar image
0 Votes"
yanxiaodi answered ·

I prefer to create another viewmodel for your model. Let's say your model's name is MyModel. If you want to update the UI for each property of MyModel, every property should implement INotifyPropertyChanged. No need to create them again in the viewmodel. In this case, feel free to create a MyViewModel which has the same properties but implements INotifyPropertyChanged. Then have a mapper to convert MyModel to the new MyViewModel. Then include it in your current viewmodel. That's just a nested viewmodel.

Basically, most of the mvvm frameworks for uwp have a base class, eg, BindableModel, which looks like a light viewmodel(supports INotifyPropertyChanged but may not have lifecycle events). You could just inherit it to implement your bindableModel to make the life easier.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Yeah I see your point. I still think that would quite a lot of duplication (although I could use AutoMapper) so I think implementing INotifyPropertyChanged on the MyModel directly is probably better.

0 Votes 0 ·