Question

I’m taking the first steps into the MvvmCross framework and I’m trying to decide the best approach in terms of project and classes structure. My biggest concern now is to decide how should I organize my viewmodels in order to share data between them and at the same time to follow the mvvm guidance.

I have simple example with to views and respective viewmodels (Main and Configuration). The main view has some controls binded to properties in the viewmodel. The configuration view enables the user to change text color, number of items in the list, etc... When the user changes the configuration, this should be reflected in the main view.

My first approach was to create separate view and viewmodels. But how could I notify the main view that the configuration was changed? I saw the Sphero project under Github/Slodge and I realized that a viewmodel has direct references to other views. In this way, it is fairly easy to notify the main view each time the configuration changed. But isn't this a deviation of the decoupled viewmodels that mvvm recommends?

Could I get some insights on the best way to approach this type of class structuring?

Was it helpful?

Solution

the best way to approach this type of class structuring

In my opinion, the most important measure for "the best way" is to choose a way that means your app works.


The example you've looked at - sphero ball control - has examples both of independent view models (home, gangnam, about, sphero, etc), and it has an example of some view models that know about each other - the sphero view model and it's sub view models.

In this particular case, the reason those view models all know about each other is because they are all part of a single display - they are designed to sit together inside a single grid, pivot, or tabbed UI. To assist with them cooperating I've given them references to each other via IParent and IChild interfaces.

isn't this a deviation of the decoupled viewmodels that mvvm recommends?

I admit this does mean that the design isn't perfectly decoupled, and that if I need to move or reuse those child vm's in the future, then I might need to do a little code refactoring - but right now the design works well for me, and I personally am happy do that refactoring in the future if I need to.


My biggest concern now is to decide how should I organize my viewmodels in order to share data between them and at the same time to follow the mvvm guidance

If you are building a composite (tabbed) view and you're not happy using aggregated view models (like the sphero vm and it's subviews), then please don't.

I'm sure the same effect could have been achieved in sphero using one big view model, using multiple view models communicating via a messenger or using multiple view models communicating via one or more custom services.

For the particular example you give - of a configuration and main view, I don't think this fits the tabbed scenario - and I would probably code this using a messenger - that would provide me with a flexible mechanism for broadcasting and receiving change notifications around various parts of the app.

However, other designs are definitely available and viable - eg you could easily just ask the view model to refresh its configuration each time its shown (doing this would require hooking into onnavigatedto, viewwillapear and on resume calls in the views).


In summary:

  • I agree with your general goal of writing independent view models and making them communicate via services.
  • in the case of a main page and a settings page, I probably would use 2 separate vm's and a messenger
  • In the case of tabbed/pivot UIs I personally have broken away from that perfect paradigm - but there's nothing in mvx that forces you to follow me

OTHER TIPS

In the project I am building with MvvmCross, I decided to use viewmodels to represent the views (screens) and their state. My viewmodels are connected to SQLite database using ISQLiteConnectionFactory. I use models stored in the SQLite database to represent the state of the things in the project. My view models get the models from SQLite database, analyze them and react upon.

Example. I have a screen where a user can flag that he/she wants a piece of data downloaded on the device. My model has a flag whether the that piece of data should be downloaded or it has been downloaded. When I open another screen that is responsible for downloading data, it looks into SQLite for any models are marked for downloading and reacts upon it.

This is how I decided to share the data between viewmodels. The advantages is that data is always persisted in the database, force closing an app won't result in lost data (or something not happening as it was expected).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top