0

As part of a Xamarin.Forms application I have implemented a custom navigation header. The Navigation Header is simply a Content View that has its own View Model. Pages which need to participate in the navigation experience of the application include this content view within them.

This application is using Prism 7 and to perform navigation within View Models I would like to use the Prism INavigationService. The issue I have with this is getting a reference to the INavigationService inside the View Model for the navigation Content View.

Accessing the INavigationService in a ContentPage is trivial, simply have this injected using constructor injection, the problem is that injecting INavigationService into the View Model for a Content View is not possible using prism 7 - this is confirmed by Brian Lagunas in his reply to this topic on the Xamarin Forums.

In his response Brian quotes as follows:

You can't inject the INavigationService into a ContentView's VM. You should either expose a property that you can bind to from your VM, or set it in code when the ContentView is loaded.

With the above in mind, what would be the approach to getting a reference to the INavigationService in the View Model of a Content View? I already have the wiring of the Content View to its View Model working correctly.

Chris Lawrence
  • 481
  • 1
  • 6
  • 14
  • Which is your question if it is not answered by `You should either expose a property that you can bind to from your VM, or set it in code when the ContentView is loaded.`? – Haukinger Jun 09 '18 at 21:00
  • I guess my question would be what a possible implementation of the two suggested solutions could/would look like? – Chris Lawrence Jun 09 '18 at 21:04
  • I am guessing that you are creating custom control or some view that you want to reuse... why don't you just expose some Command and use that command in your page xaml and viewmodel of your page and there you can use INavigationService? Does this makes any sense to you? – Almir Vuk Jun 09 '18 at 21:32
  • Yes, this is a shared view that is basically the navigation area at the top of an iOS and Android application. You are referring to exposing a command, this would be from the shared view model I assume? If the implementation of this command is in the shared view model, surely this leaves the same scenario, the command wouldn’t have access to the INavigationService? – Chris Lawrence Jun 09 '18 at 21:56
  • Or are you referring to exposing a command on the shared view that is then implemented in the pages that use the view? If so, this could work. As this view will be used on every page almost, I was hoping to avoid having to implement the navigation calls outside of the shared view model, but perhaps this is something I won’t be able to avoid. – Chris Lawrence Jun 09 '18 at 22:06
  • Yes. You can add one bindable command in your reusable view. That command can be helpful for you to use it in your Page and View Model, to execute some method in ViewModel which can handle your navigation when that command is executed. – Almir Vuk Jun 09 '18 at 23:19
  • Yes, that is an approach that could work. It is certainly something that I will implement and test – Chris Lawrence Jun 09 '18 at 23:31
  • Ok, let me know, I will be glad to know if this was helpful for you. – Almir Vuk Jun 09 '18 at 23:47
  • @AlmirVuk I did some implementation of your suggestion, exposing a bindable command from the shared view. I don't think this is going to work for my scenario. It works well when the shared view doesn't have it's own View Model, as the data context is inherited from the page. But when the shared view has its own View Model (which mine does) The command on the page View Model is never found, because the data context of the shared view is its own View Model. I am going to try just raising an event from the shared view and handling this with a command in the view model of the page. – Chris Lawrence Jun 11 '18 at 03:03
  • @AlmirVuk - Update for you. I have now managed to get this working using the method that you suggesting, exposing a command that I can bind to. If you want to add this as an answer I will accept this as the solution – Chris Lawrence Jun 15 '18 at 16:03
  • Nice, I submitted my answer, thank you! Glad to hear that you resolved your issue. – Almir Vuk Jun 18 '18 at 08:07

1 Answers1

0

You already mentioned that there is no way to use INavigationService in your View Model for Content View (your custom control).

One of the easiest and simplest ways to resolve this is by adding bindable command in your Content View (custom control), having this bindable command you will be able to use that command and bind to it from ViewModels of your pages.

With this approach you can use INavigationService in your page ViewModel in a standard way and navigate from page based on command execution in your ContentView.

In other words you can handle your navigation from ViewModel when that command from reusable view is executed.

There is a lot of examples how to achieve this, you can use this one from another SO thread.

Wishing you lots of luck with coding!

Almir Vuk
  • 2,983
  • 1
  • 18
  • 22