We are considering migrating a UWP app to Xamarin Forms. We need to be able to save the state of complex objects such as an order form when the user navigates away and retrieve that state when the user navigates back. We also need to be able to cancel navigation from a viewmodel.
We use MVVM, so my questions are from that context, but we like to think of ourselves as pragmatic rather than zealous about such things.
In UWP we use the Template10 library to save state in the OnNavigatingFrom event. We retrieve the state in the OnNavigatingTo event. This works even when the app back button is clicked.
Xamarin Forms doesn't seem to have built-in events to handle navigating to and from a viewmodel.
Prism for Xamarin Forms has OnNavigatingTo but does not appear to have OnNavigatingFrom. On some pages we use OnNavigatingFrom to prompt the user to save or discard. OnNavigatingFrom can be cancelled in response to a dialog.
It also appears Prism does not handle navigation using the application back button or the hardware back button. We need to be able to handle navigation to and from viewmodels regardless of how the navigation was initiated.
I've spend a couple of weeks researching these issues and testing scenarios in Xamarin Forms. I assume I have missed something in my ignorance. I understand primitive types can be persisted to application properties, but it would be nice if we didn't have to serialize and deserialize complex hierarchical objects ourselves.
Is there a paradigm/framework in the Xamarin Forms world that will:
handle events navigating to and from a viewmodel
allow navigation from a viewmodel to be cancelled in response to a dialog
allow state to be saved navigating from a viewmodel
allow state to be retrieved navigating to a viewmodel
fire navigation events regardless of how the navigation was initiated?
I understand there are many questions in this one question, but we are not looking for individual solutions, but a paradigm or framework which gives us the tools to solve them all in Xamarin Forms, such as T10 does for UWP.
Not sure how long you spent researching Prism for Xamarin.Forms, but it provides everything you said it didn't.
You should start with this video. It's a little old, but it will get you started.
https://www.youtube.com/watch?v=DYRLcqG2BAY
As far as actually persisting the data, that's for you to decide. Prism will give you the hooks to do it.
Related
The following example uses an MVVM approach to update a property based on a picker selection:
https://github.com/xamarin/xamarin-forms-samples/blob/master/UserInterface/BindablePicker/BindablePicker/BindablePicker/SimpleColorPickerPageViewModel.cs
It uses OnPropertyChanged("SelectedColor"); when the selection changes to update another property.
I have two questions:
Firstly, is there any advantage of using this approach over the normal OnSelectedIndexChanged event in the xaml.cs?
Secondly how would i use this approach if i wanted to update a particular item for my custom object in my viewmodel. For example, if the selected item changed in the above example, store the value in another object in the view model?
It just seems long winded to the OnSelectedIndexChanged approach, but guessing there are advantages i'm unaware of?
basicaly i have a number of dropdowns on a page, and with each change, i want to update the object in my view model which will be sent back to the server with a rest service.
Picker.SelectedIndexChanged is not as straigthforward since you will still need to index the list and find which item and since it's not a command, you need to implement it in Code Behind.
You just said that you need to send rest http requests, so it means that your app is fairly complex so you will probably need ViewModels and to keep your code coherent, you should apply the same pattern to all pages.
For the sake of keeping things neat and tidy I always implement MVVM even if the Page logic is not very extensive.
MVVM also facilitates (a lot) unit testing your application.
But in the end, it's all about taste.
Background:
We're using Caliburn.Micro 3.0.0-beta2 with a WPF + Xamarin iOS / Android project and we want to ensure the view models can be cross platform to reuse as much code as possible.
We've been looking at how to abstract our our navigation to be testable, cross platform and so callable in the view model rather than the views.
I was wondering if anyone had suggestions about how we should handle our app navigation. Our screens require us to inject some data such as database ID's into screens as we're navigating around. Currently we've done this with a view first approach by injecting the data into the view and having that pass it into the view model, but this doesn't feel ideal as it should really go into the view model as it's view logic (right?).
The view model is created for the view view using ViewModelLocator.LocateForView(this); and this then satisfies the rest of our dependencies using the SimpleContainer.
We Understand that navigation hasn't been implemented into 3.0.0 yet according to https://github.com/Caliburn-Micro/Caliburn.Micro/issues/142. We're really looking for a way we could do navigation that may be similar to the Caliburn.Micro solution implemented soon, with a hopeful view to contribute towards this if possible.
Questions:
How would we go about getting the data into the view model rather than the view to make it easier to test and more similar to how our WPF application will need to work?
Is this even sensible for a mobile app or should we be taking a view first approach? If so, what would be a testable approach for this?
Unless you have setup Caliburn.Micro for view-first approach (can be done there is a sample for this) the framework is almost completely viewmodel first in nature. I find it rather difficult to work in view first. Most of my "screens" are developed around the view model in question. With that in mind I also at times have multiple views for each viewmodel depending on the operation (add/ edit/ details/ list) for example.
1) DI, usually through repository or other context of that nature then using BindableColllection to hold and notify of changes to the view. Pretty much the same as WPF would work. Most recently my code has started to be cross platform (WP to WPF, now more Universal) to help reduce my headaches. Most of the patterns used are DI(SimpleContainer), Repository (EF 6x), Pub/Sub (IEventAggregator). The one exception is Repository but to an extent I still use it on WP but since I use Sqlite, up until recently EF was out of the question (EF 7 to the rescue)...
2) Do what is comfortable. If you are use to using Fakes then do it. It shouldn't matter as long as you have the correct results you are looking for in the end. Of course I am sure each test is going to be slightly tweaked for the platform they are tested on. Since each platform has its own nuances that you have to take into account.
I am new to knockout.js. Few moments back I read the headline features of ko.
I could not understand is ko really MVVVM? Because all they talk about is data binding and the ease of it. But I am sure MVVM is more than data binding isn't it?
Yes, knockout.js does apply the MVVM pattern. It's explained in the documentation:
A model: your application’s stored data. This data represents objects and operations in your business domain (e.g., bank accounts that can perform money transfers) and is independent of any UI. When using KO, you will usually make Ajax calls to some server-side code to read and write this stored model data.
A view model: a pure-code representation of the data and operations on a UI. For example, if you’re implementing a list editor, your view model would be an object holding a list of items, and exposing methods to add and remove items.
Note that this is not the UI itself: it doesn’t have any concept of buttons or display styles. It’s not the persisted data model either - it holds the unsaved data the user is working with. When using KO, your view models are pure JavaScript objects that hold no knowledge of HTML. Keeping the view model abstract in this way lets it stay simple, so you can manage more sophisticated behaviors without getting lost.
A view: a visible, interactive UI representing the state of the view model. It displays information from the view model, sends commands to the view model (e.g., when the user clicks buttons), and updates whenever the state of the view model changes.
When using KO, your view is simply your HTML document with declarative bindings to link it to the view model. Alternatively, you can use templates that generate HTML using data from your view model.
In addition to the answer already provided, there are a few things to keep in mind -
MVVM
Knockout is MVVM because it supports a good separation of concerns. Unlike other JavaScript libraries, such as jQuery, it's goal is to not pollute the view with that which does not concern it.
The view model's purpose is important to understand. It does not attempt to manipulate the DOM because only logic required to serve up data to the view is placed inside of it.
The view's purpose is only to present (render) the data. No logic, validation, or other logic code goes here.
The model is the only place where Knockout can get a bit tricky. It is generally a good accepted practice to place a separate model in your project for Knockout to use, but many developers have found the ease of mixing the model into the view model. The reason for this is obvious (some models are very basic) but again this is only out of ease of implementation.
MVC vs MV*
Surely there are other answers on SO.com that attempt to answer what is MV*, but I wanted to throw my $0.02 in here - Other libraries or frameworks speak to the fact that they are MVC or MVP or MV(whatever) based but Knockout is the only one that I have found that practices what it preaches in this regard. If you have the time and desire look at the structure of other frameworks such as Angular or Ember and you will see there is a blurred line that exists, and more or less they are simply using an MVVM based pattern but calling it something different.
Well I guess it can, however I am working on a project where all styling and UI layout manipulation is done in the knockout js ViewModel file, which is not good practice.
I'm using MVVM and Unity, I've understrood how to show the shell View (MainView with its MainViewModel) but I couldn't find the right way to instantiate other windows, for example : Details Button that opens a new form and show other details.
So, I'm looking for a common way how to instantiate/Call other Views(WPF windows) with their ViewModels using MVVM and Unity.
This answer may help with understanding how to link multiple views/viewModels together. I don't typically find myself needing to open additional windows just displaying different views in the current window.
Please let us know if you're looking specifically for an MVVM solution for opening new windows.
Take a look at this answer: Handling user interactions in MVVM. You can utilize an interaction service to instantiate new WPF windows will still remaining decoupled.
You can also provide indirect communication in WPF by leveraging the Mediator pattern to publish a message from a view model that causes a new view to be instantiated. This answer Simple Mediator implementation gives a quick overview.
I recommend you read over the User Interaction Patterns guidance, as it covers many of the scenarios you will face when using MVVM.
I have read a lot of gwt-mvp questions that are asked here, but since i'm totally new to this design pattern I would like to ask some questions:
[1] The Activity-Place pattern is a different pattern than mvp?
[2] In the MVP pattern presenters contain the logic. Now the logic of the widgets/controls is defined in the Activities?
[3] The CustomPlace classes are fixed (as the Eclipse plugin constructs them) or can i put data/methods and what kind?
[4] What is the use of the Presenter interface inside a CustomView? What data/methods would make sense to add into it?
[5] I want to build an application that will use many data structures that will be saved into a database. I have read some other posts here and I will make the Model part of MVP live inside each Activity. So i think to create each time the data structures of each activity at start and load its values (if necessary from db) and will update the database after the user goes to another view. What do you think about this approach?
Let's start by debunking one myth: Activities/Places have nothing to do with MVP. Places is about navigation, Activities are about "componentizing" the UI wrt Places. On the other hand, MVP is a design pattern, it's about how to organize your code.
Many people are using their activities as their MVP-presenters, but it's not enforced. The GWT team is trying a new approach where the activity is distinct from the presenter (work underway in the mobilewebapp sample if you want to follow what's going on there). You could also have your activity being your view and making use of an "internal" presenter (similar to how Cell widgets work)
A Place is more or less a URL. You can put whatever you want in it. I'd suggest making places immutable though: build a Place, goTo it, make use of its properties to build your UI.
That's about MVP then. This is only needed to decouple your view and presenter, mostly to make mocking in unit tests easier (this is particularly of the view interface though, not much for the presenter one, unless writing a test harness for you views). In some cases, you might also want to use the same view with distinct presenters; they'll all implement the same interface so the view can talk back to them.
How about the closing of the window/tab? I'd rather use a periodic auto-save, or an explicit save button; and implement mayStop so it prompts the user when there are unsaved changes (similar to how most desktop office apps work —e.g. MS Word or LibreOffice—, and GMail if you try to navigate away before your mail draft is auto-saved)
The Activity-Place is an implementation of the pattern. Google introduced gwt-mvp pattern at Google IO, but only provided it's implementation as part of GWT about a year later.
Yes Activities contain business logic. No, widgets/controls usually do not contain any logic, they just fire events based on user action. The logic that acts upon those events is written by user and resides elsewhere.
I don't use Eclipse, so wouldn't know about Places generated by it. Normally custom Places can contain custom fields and methods. For example they can contain custom place token arguments, i.e. if place token is "#place:id1", than your custom Place could contain field holding this argument.
When View needs to call/access Activity, it does so via Presenter, which Activity implements. For example when user enters all data in a for and presses submit, then you could have a method in Presenter named submit(formData).
Preparing/loading data in activity.start(..) is a normal way of doing things. If particular activity is used a lot, then you might consider caching the data if appropriate.