Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM: Notify view when model status changed

This is a specific question about the MVVM pattern best practice. I'm using MvvmLight Library. It goes like this: My model, say "Flight", implements some business logic that can start, pause and stop flights via methods. Each method does its logic to make the functionality happen whether it's playing stopping or pausing the flight. One important variable that changes is a status enum which indicates the flight status - playing, stopped, or paused. As said the status variable (and property) are defined in the Model. On the other side the flight class is wrapped by a ViewModel class which contains a Status property that wraps the status variable in the flight model, and also RelayCommands that connect to the flight model play stop pause methods.

Here the problem begins: When I execute one of the commands through the view, it executes the method in the model so that the status variable itself changes directly, but it only changes in the model.. The status property in the ViewModel doesn't know whether the wrapped variable have been changed, as it was changed directly... That means if some view element is binded to the status property, it won't change upon command execution..

I know several means to solve this but I'm asking for a fair solution that won't break the MVVM pattern (like using INotifyPropertyChanged in the flight class in the Model )

like image 839
Giora Ron Genender Avatar asked Mar 30 '26 15:03

Giora Ron Genender


2 Answers

There is no magic bullet solution to this type of problem. Your ViewModel and Model need to be designed in a way that allows the information to propagate to the View; if this is not possible, then the design is flawed and needs to change.

Here's a couple of things you should look into:

  • If the Model's state-modifying methods are documented to execute synchronously, create methods on the ViewModel that forward the action to the Model and then immediately query its state. Use these methods for the implementation of the RelayCommands.
  • If the Model's methods are not synchronous then there should be some mechanism available to the Model's clients to notify them when the methods have completed. This can be done through continuation callbacks, events, or perhaps even with INotifyPropertyChanged.
like image 175
Jon Avatar answered Apr 02 '26 13:04

Jon


As you mentioned above, your ViewModel should wrap Model at the following way:

class Model
{
   public int State{get;private set;}
   public void Fly()
   {
      State=1;
   }

   public void Stop()
   {
      State = 2;
   }
}

class ViewModel : ViewModelBase
{
   int State{ get{ Model.State;}}
   ...
   OnFlyCommand()
   {
      Model.Fly();
      NotifyPropertyChanged("State");
   }
}
like image 43
Michael Barabash Avatar answered Apr 02 '26 12:04

Michael Barabash