I am currently investigating all possible solutions to be able to inform the user, ie pop a dialog, when there is a decision he needs to make. This is a common problem with MVVM pattern and I am trying to solve it for MvvmCross framework.
Possible solutions could be:
- Customize the MvxPresenter to be able to show dialogs, but that looks a bit ugly to me
- Put a Dialog interface in the Core project and use Inversion of Control to inject the implementation from the UI project to the Core project
- Use the MvxMessenger plugin and share messages between the Core and UI project. Sounds like a good idea but maybe more complicated to develop...
What would you suggest?
As Eugene says, use the UserInteraction plugin. Unfortunately, there's not currently a Windows Phone implementation, so here's the code I've used in the interim:
You'll notice that not everything's implemented, and even those bits that are are limited (you can't set the OK ad Cancel button text, for example)
Of course, I needed to register this in setup.cs as well:
You just can use MvvmCross UserInteraction plugin from Brian Chance
Dialog input is an interesting topic that doesn't always fit well with the flow of Mvvm Data-Binding.
Generally, some use cases of Dialogs are for things like:
For some of these items, I'd suggest that mainly these could be modelled as purely View concerns. For example, requesting single item selection is commonly done from compound controls labels which display 'pickers' when tapped - e.g. like an MvxSpinner in https://github.com/slodge/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Droid/Resources/Layout/Test_Spinner.axml#L16
For general cases, where you want the shared ViewModels to drive the user flow, then options which are available within MvvmCross include the 3 you list, all of which seem viable to me, but I agree that none of them is perfect.
As an additional suggestion, one nice architectural suggestion is from Microsoft's Pattern and Practices team. In http://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx, they suggest a
IInteractionRequest
interface which can be used within data-binding especially for this type of situation.Their reference implementation of this is:
An example ViewModel use of this is:
and the ViewModel can raise this using:
where
Confirmation
is a simple class like:For using this in the Views:
The MSDN link shows how a Xaml client might bind to this using behaviours - so I won't cover this further here.
In iOS for MvvmCross, a View object might implement a property like:
This View property uses a
WeakReference
-based event subscription in order to channel ViewModelRaise
events through to a ViewMessageBox
-type method. It's important to use aWeakReference
so that the ViewModel never has a reference to theView
- these can cause memory leak issues in Xamarin.iOS. The actualMessageBox
-type method itself would be fairly simple - something like:And the property could be bound in a Fluent Binding set like:
For Android, a similar implementation could be used - this could perhaps use a
DialogFragment
and could perhaps also be bound using aView
within XML.Note:
IInteractionRequest<T>
andInteractionRequestedEventArgs<T>
definitions - but, for the scope of this answer, I kept to the 'basic' implementation keeping as close as I could to the one presented in http://msdn.microsoft.com/en-us/library/gg405494(v=pandp.40).aspx