Matt Burland
Matt Burland

Reputation: 45135

Create view from multiple view models

I'm working on figuring out mvvmcross and if I can use it for an iPhone (and eventually iPad and Android) app I'm going to develop. The MVVM pattern is really powerful and works great for me, but I have several views where I need to add a navigation control that will allow the user to jump to several different other views and I'm wondering what's the best way to do it.

Right now, I've created a NavigationControlViewModel which exposes a collection of NavigationLinkViewModel which have a link text property and a command that will show the appropriate view. But to add this to a view for, say, MyViewModel is a little tricky. Right now what I've done is add the NavigationControlViewModel to MyViewModel so that I can bind it in MyView:

    private NavigationControlViewModel _nav;
    public NavigationControlViewModel Navigation {
        get {
            _nav = _nav ?? new NavigationControlViewModel (Mvx.Resolve<INavigationService> ());  
            return _nav;
        }
    }

This works, but doesn't seem as nicely contained as I'd like to be. I still need to add controls to MyView for the NavigationControlViewModel and then add it to every other view that needs it (as well as adding it to their view models).

What would be the best practice for handling this sort of thing in iOS and MVVM?

I've seen the video on using a split view, but I'm not sure if that's the best approach. I need a vertical split and I only need it on some views, not every view.

Upvotes: 0

Views: 924

Answers (1)

Stuart
Stuart

Reputation: 66882

For sharing the navigation mechanism between view models, I guess you can use either aggregation as you have done NavigationControlViewModel or you can use inheritance with all the navigation items in a BaseViewModel class.

I personally would happily use either of those but would make sure to expose all my Navigation options as ICommands - simply because that's the way .Net-style data-binding generally expects 'action hooks' to be presented. Note that there is a reflection way of generating ICommand's - see http://slodge.blogspot.co.uk/2013/03/fixing-mvvm-commands-making-hot-tuna.html

For actually presenting the ViewModel via a View on the screen... I'd encourage you to believe that you can do whatever you and your UX/design team want to.

Some of the standard presentation approaches are available via: UINavgiationController, UISplitViewController, UITabBarViewController, UIPopupView and PresentModalViewController - and you are free to use these and to combine them together - e.g. you can have a navigation controller which two layers deep shows a modal view which contains a split view with two children...

Beyond the standard approaches, there are plenty of other UI design paradigms that people have selected:

By default, MvvmCross provides you with a 'whole page' presenter which presents every View-ViewModel pair the same way inside a UINavigationController. As you've seen in the N+1 video you mention, you can easily override that behaviour and you can then choose to present View-ViewModel pairs in any way you like - e.g. you can choose to present some whole page, some using a fly out, and then some using tabs.

Because an IMvxTouchView presenter is just C# code, and because we devs love writing C# code, we can implement whatever wonderful logic we want to within a presenter including code that tests what is currently being shown in order to determine where to show the next page.

I can't comment on what 'best practice' is for making a design look nice.

But I do believe that if you stick with showing your view models via ShowViewModel then that will allow you the most flexibility in what presentation strategy to use on each platform.

Some more on presenters is available via http://slodge.blogspot.co.uk/2013/06/presenter-roundup.html

Upvotes: 1

Related Questions