Louisa Bickley
Louisa Bickley

Reputation: 297

How to navigate between pages using Prism in Xamarin.Forms?

I'm trying to inject INavigationService into my ViewModel, so I can navigate between pages, but I don't know how to register ViewModel with parameter. Here's my App:

<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
             x:Class="PrismDemo.App" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
    <prism:PrismApplication.Resources>
        <ResourceDictionary>

        </ResourceDictionary>
    </prism:PrismApplication.Resources>
</prism:PrismApplication>

and...

public partial class App
{
    INavigationService _navigationService;

    public App(IPlatformInitializer initializer = null) : base(initializer) { }

    protected override void OnInitialized()
    {
        InitializeComponent();

        _navigationService = NavigationService;
        NavigationService.NavigateAsync("MainNavigationPage/Start");
    }

    protected override void RegisterTypes()
    {
        Container.RegisterTypeForNavigation<MainNavigationPage>();
        Container.RegisterTypeForNavigation<StartPage, StartPageViewModel>("Start");
        Container.RegisterTypeForNavigation<MiddlePage, MiddlePageViewModel>("Middle");
        Container.RegisterTypeForNavigation<LastPage, LastPageViewModel>("Last");
    }
}

How can I inject _navigationService into ViewModels?

Thanks for help

Upvotes: 0

Views: 825

Answers (2)

Yehor Hromadskyi
Yehor Hromadskyi

Reputation: 3388

If you are using Prism, than you should inherit your App from PrismApplication:

instead of public partial class App should be public partial class App : PrismApplication.

No need to declare INavigationService _navigationService; in your App class, because it's already declared in PrismApplication as NavigationService property.

Prism uses IUnityContainer as Dependency Injection framework, which means for you, that all, that you will register in container:

Container.RegisterType<ISomeService, SomeServiceImplementation>();

Unity container will automatically inject in constructor:

Define a constructor in the target class that takes as a parameter the concrete type of the dependent class. The Unity container will instantiate and inject an instance.

PrismApplication registers INavigationService in a container, so, as I understand, you don't need to register your own instance and you could just add parameter of type INavigationService in constructor of view model and unity container will inject instance of registered type. The important thing, that you should give an exactly the navigationService name for your parameter, because Prism "expects" such parameter name for navigation service.

Upvotes: 1

Dan Siegel
Dan Siegel

Reputation: 5799

You don't actually have to register the ViewModel directly as long as you have followed the convention {MyProjectName}.Views.{MyPage} and {MyProjectName}.ViewModels.{MyPageViewModel}

To use INavigationService in the ViewModel simply add it to the Constructor. Remember it is a named service so it must be named navigationService. You can check out several examples in the Samples Repo.

public class MyPageViewModel
{
    INavigationService _navigationService { get; }

    public MyPageViewModel(INavigationService navigationService)
    {
        _navigationService = navigationService;

        NavigateCommand = new DelegateCommand<string>(OnNavigateCommandExecuted);
    }

    public DelegateCommand<string> NavigateCommand { get; }

    public async void OnNavigateCommandExecuted(string path) =>
        await _navigationService.NavigateAsync(path);
}

Upvotes: 1

Related Questions