One of my colleagues (he is Danish and he is stinky) who has been using MEFedMVVM NavigationExtensions asked to add functionality so that you can Navigate to a View from code.
I wanted to be careful adding this feature to make sure the ViewModel stays clean. So lets see what we need to do this
Lets first rewind and look at the current MEFedMVVM NavigationExtensions… It has 3 Attached properties
The properties are
- NavigateTo – which is the uri for the view
- NavigationHost – which is the UI element to host the view rendering
- NavigationParameter – which is a parameter to be passed
There is a lot of UI specific stuff in the above so we need to be careful not to make the ViewModel dirty. The ViewModel needs some kind of “UI service “ so that it can ask this service to navigate to a view and pass a parameter (something like the IVisualStateManager of MEFedMVVM); something like this >> Navigate(string viewName, object parameter) . It also need to pass the host so that the NavigationExtensions know where to render this view.
Here is what we came up with ..
As you know (or maybe not, in that case please read this) MEFedMVVM has support for UI Services, if your service implement IContextAware, MEFedMVVM will inject your service with the View instance that asked for the ViewModel to be injected. We leverage this and have an INavigationInvokerFactory. The INavigationInvokerFactory exposes a method that takes a string which should be the name of the host element. Internally the INavigationInvokerFactory will call the FindName(“[your parameter]”) on the element that was sent by MEFedMVVM IContextAware. The CreateNavigationInvoker method will return an INavigationInvoker which can be used to Navigate to a view.
From here you now have an INavigationInvoker and all you have to do is call the Navigate method passing the uri for the View you want to render and the parameter you want to pass
And that’s all folks… Enjoy