Alternatives on passing parameters from ViewModel to ViewModel in MvvmCross - c#

We are at the preparation on porting a huge windows mobile app to Xamarin
and we are using MvvmCross to help us with the Mvvm.
The application is huge, where workflows live between several pages. So there is a need to pass states/objects between pages. As those states can be big, it does not make sense to serialise them between navigation calls.
My question is: what are any proven or used alternatives to pass objects between view models? Is there some session manager?
Note: we are starting with Android, so maybe there is also good an Android only solution.
Hint: I posted this question on Programmers as well, not sure what's the better platform for this: https://softwareengineering.stackexchange.com/questions/285219/alternatives-on-passing-parameters-from-viewmodel-to-viewmodel-in-mvvmcross

A couple of options I use are:
1) Persist state to a SQLite database and pass an identifier from ViewModel to ViewModel. This is simple and ensures that the state remains even between app restarts.
2) Another option, which is useful in a wizard-like setting is to use a Cache service. I simply created an interface to add and remove entries in a cache by key. I treat it like a standard MvvmCross service and use IoC to inject into my view models. At the start of the process, create a GUID to use as your key, add your state to the cache. Simply pass the key to the next view model, where it can retrieve the state from cache.

Related

Understanding application flow with MVVM

I am having a hard time understanding how MVVM is used in case of more complex applications. All the examples I can find are extremely basic Apps.
Let's say I have a "Package Delivery" application. To perform a delivery I have to do 3 steps:
Scan the package
Enter any damages or problems with the package
Let the recipient sign on the device
All this information gets validated on the device and then sent to the backend.
In MVC I would implement this like this:
The DeliveryController handles all of the logic. This includes navigation between pages, fetching of API data and validating all of the data once it is all collected.
The controller acts as the "Connection" between the Views and collects all the information and brings it together.
But how would this be done in MVVM? Where would all the data be brought together? Most implementations of MVVM I can find do something like this:
In this, the data entered in each View would have to be passed to the next ViewModel until the end of the chain is reached. At that point the SignatureViewModel would do the validation and make the API call. That seems very weird and like it would get very confusing, since data would just be "passed through" multiple ViewModels just to have it at the end of the chain.
Another option I see would be that each ViewModel handles it's own data:
Here for instance the DamagesViewModel would validate and send the data it's own View handles. The big issue with this is that data does not get sent as a whole. Also there can not be any validation of the entire data before it is sent.
My last idea would look like this:
This adds a DeliveryViewModel that essentials acts like the DeliveryController does in MVC. It would handle which ViewModel to navigate to next, handle what API calls to make and validate all the data once it is entered.
To me (as someone who has mostly used MVC) this last options seems most sensible. But I also feel like it might miss the point of MVVM.
How is this usually done in MVVM? I would really appreciate any pointers. Links to articles that explain this well are much appreciated.
Also if anyone knows of any publicly available repositories or projects that have this kind of pattern in them, I would love to see them.
Even when using MVVM I still use some form of a controller and consider ViewModels as basically transformation of data to facilitate the view.
So for me there is still a service or controller layer that completely separates the middle and back end tier from the rest of the architecture.
View models come into play depending on the consumer/app - fetches data from the service tier, transforming the data, validating etc for the purpose of a consumer/app/etc.
I have struggled quite a bit with the same thing. Especially since I’ve used MVC quite a lot.
I think the most important thing to consider is that MVVM is not meant to solve exactly the same things as MVC. You can still implement a controller outside of this pattern to complement it. It also changes quite a lot the general design of the application.
One mean to do it that I have used is to implement the controller as a singleton that can be shared between VewModels. This controller can per example be injected into the ViewModels using dependency injection.
Viewmodels could then for exemple subscribe to events coming from the controller to update.
But this is one way to solve this problem among others.
MVVM is a way to organize code. It’s one way to separate your user interface from your logic.
I have found a blog where you can have a look where MVVM architecture is described perfectly.Though here writer demonstrates MVVM for windows form app but at least you can get some idea about architectural design of MVVM.
https://scottlilly.com/c-design-patterns-mvvm-model-view-viewmodel/
Also please have a look into this repo.
https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example

Design Issue (Unity, Reflection)

I am currently developing a Microsoft Word Add-In that communicates with a backend via webservices. The dialogs in this Add-In are created with WPF and I make use of the MVVM pattern. The viewmodels communicate with the repository over services. In order to decouple viewmodel and services I use the DI-container framework Unity.
There is some kind of state (I call it "Context", similar to the http-context) that depends on the active document at the time a window/viewModel was created. This context contains stuff like the active user.
Since a picture is worth more than a thousand words, I prepared a diagram to illustrate the design.
Now my problem is, that when a service method is called, the service needs to know what the active context is in order to process the request.
At the moment I am avoiding this problem by having one service for each document. But since this cuts across the statelessness of services, I don't consider it as a durable solution.
I also considered passing the context to the viewModel, so that I can pass it back to the service when calling a method there. But I see three problems here:
Technical Problems:
Each time I want to resolve a Window with Unity I would have to pass a ParameterOverride-object with the context - what creates dependencies to the concrete viewModel implementation.
=> Or is there a better way to achieve this with unity?
Cosmetical Problems:
I would have to pass the Context as object since the class for it is part of the startup-project and the ViewModels are not. When I now want to obtain data from the context, I'd have to cast it.
Consider a windowViewModel that contains data for a TreeView with hundreds of TreeViewItems. I would have to pass the Context to each of these "TreeItemViewModels" if I'd want to call a service-method in one of these.
So I'm wondering if there is a way of automatically "injecting" (maybe reflection?) the context into the viewModel at runtime without the viewModel knowing anything about it. This is probably impossible to achieve with Unity, but I'm always open to being convinced.
On the other side, when a method on a service is called, the injected context is automatically extracted (maybe by some kind of layer in front the actual service) and saved into some globally accessible property.
I hope that some of you can help me. I appreciate any kind of idea.

Reuse IMobileBarcodeScanner in cross platform app?

I am writing an app using xamarin, mvvmcross, and zxing.net.mobile. I would like to be able to use an instance of IMobileBarcodeScanner in the portable class library to do the scanning.
The issue I'm running into is that the droid version of IMobileBarcodeScanner requires a context to be passed into the constructor. I'm guessing we'd need to register the type in the view constructor so we can pass the correct context.
Since there will be multiple views, would I be able to register a different instance of IMobileBarcodeScanner for each view? Or, could I make the IMobileBarcodeScanner a public property on the view model and set it from the view constructor instead?
Thanks for your help!
There are two main ways I've worked with barcode scanners in the past.
I've launched them as 'new pages' - including using external activities and StartActivityForResult in Android
I've treated them as 'normal controls' - a bit like TextEdit fields within the current page.
When doing the first of these, I generally used a pattern similar to the PictureChooser plugin - on Android, this accesses the current context using IoC in MvxAndroidTask
When doing the second, I treat this purely as a View concern - all the ViewModel needs to provide is an ICommand and/or a string property which can be bound to the scanned event or to the scanned text.

MVVM Store State in C#

I am using MVVM with WPF, but I am having a hard time understanding the concepts behind this desing pattern.
I have a "myclass" object that is the state of the application (it stores data loaded from the repository). All pages of my application will use this data and the object should be syncronized between them all.
My first approach was to store this data in the service layer, using a singleton class. So, all ViewModel should call this service to get the data. Any modification should also call this service, and a event would be fired to synchronize all views.
I am wondering now if it would be better to store this data in the model layer...
What's be best option?
EDIT:
Adding more information:
The data stored is a list of projects loaded into a solution. Since there must be only one solution, I implemented it as a singleton. The must can interactively load, change, or remove any project.
A Service to my understanding is just something that abstracts a piece of functionality(access the file-system, access a database...) which say implements a given interface that the VM's can then use when requiring that functionality.
A Model however holds the business logic of your application and anything that will assist performing that business logic (which can / cannot implement INPC if desired)
So in essence you use a service to get something done and let go of it, a Model is more ingrained to your application
For your given use-case, I'd have the stored info in the Model and implement INPC on it so that the ViewModels get notified of changes automatically if another ViewModel makes a change to the Model.

MVVM: How to maintain data which all the view models will use?

Maybe the title is not so descriptive.
I'm working right with Galasoft MVVM framework, and I realized in my application I need all the time or use these data in the view models.
The data which I need is this Authentification model
Username : string
Password : string
IsGuest : bool
I guess it is not a good idea and the best way to pass these data through navigation.
A few months ago, I was using Prism and I remember something called Container, where you can register and save your object in all the lifecycle of your application.
Another way which I was thinking is to save it in App class, but I'm not sure if this is a good idea.
By the way, I'm working on Metro UI applications.
Don't store the data in the App because it is part of the View. To use it you would effectively have to reference the View from all of your ViewModels. A core principle of MVVM is that the Model(s) only have access to other Model items, the ViewModel has access to other ViewModels and the Model, and the View has access to ViewModels
There are a couple of choices you could consider
Create a static class AuthenticationData where this gets initialized
Pass the authentication data to the constructor for each view model
Store the authentication data in an IoC container (GalaSoft has a SimpleIoc class)
Options 2 and 3 could make it easier to mock your authentication data for testing purposes if you use an IAuthenticationData interface
For Authentication there's already something there you can use. Check IPrincipal/IIdentity interfaces. Upon authentication these are set to Thread.CurrentThread.CurrentPrincipal and can be used later.
The Container you are referring is probably Unity which is an IoC container and GalaSoft also comes with a simple one.

Categories