[StackOverflow] Xamarin.Forms and Prism - How to pass data and navigate to another view?

I decided to be more active on StackOverflow and to post my answers from there, here on the blog. I will post the answers which I think are worthy to share here on the blog. Hope you will enjoy this kind of content.

[StackOverflow] Xamarin.Forms and Prism - How to pass data and navigate to another view?

I decided to be more active on StackOverflow and to post my answers from there, here on the blog. I will post the answers which I think are worthy to share here on the blog. Hope you will enjoy this kind of content.

My answer to this questions is below:


As I can see you are already using Prism and you have a List page with Items and you want to navigate to some details page based on the selected/taped/chosen item which the user taps in the ListView.

The idea is to move as much code and logic as we can to the view model and keep our code-behind. This is pretty easy to solve using Prism and EventToCommand behaviour.

In the example and answer below, I will show you how to solve this with few lines of code, with a nice code approach.

First of all, I recommend you use EventToCommand behaviour, you can include it with prism xmlns, like this: xmlns:prism="http://prismlibrary.com", later on, you can use it with ListView.

Remove ItemSelected event from your ListView and move the markup about it to the <ListView.Behaviors> part. Here is my code sample for the ListView which binds to some ObserverableCollection of the Car models:

<ListView ItemsSource="{Binding Cars}">
    <ListView.ItemTemplate>
        <DataTemplate>
              ...
        </DataTemplate>

    </ListView.ItemTemplate>

    <ListView.Behaviors>
        <prism:EventToCommandBehavior EventName="ItemTapped" 
                                      Command="{Binding SelectedCarCommand}"
                                      EventArgsParameterPath="Item" />
 </ListView.Behaviors>

The main part here is <ListView.Behaviors>, where you can see that I am binding to the SelectedCarCommand which will be invoked when the user taps on some of the items from the list. I am using the ItemTapped event for this and passing the current "taped" item from the list as a parameter.

In order to follow this XAML part in my view model of this page, I have declared the DelegateCommand and method which will be called when the command is invoked. The view model part looks like this:

This is my CarListPageViewModel, take a look at DelegateCommand and SelectedCar method.

public class CarListPageViewModel
{
    private readonly INavigationService _navigationService;
    public ObservableCollection<Car> Cars { get; set; }

    public DelegateCommand<Car> SelectedCarCommand { get; private set; }

    public CarListPageViewModel(INavigationService navigationService, IDataProvider dataProvider)
    {
        _navigationService = navigationService;

        // Insert test data into collection of Cars
        Cars = new ObservableCollection<Car>(dataProvider.GetData());

        SelectedCarCommand = new DelegateCommand<Car>(SelectedCar);
    }

    private async void SelectedCar(Car selectedCar)
    {
        NavigationParameters navigationParameters = new NavigationParameters
        {
            { "selectedCar", selectedCar }
        };

        await _navigationService.NavigateAsync(nameof(CarDetailsPage), navigationParameters);
    }
}

As you can see we have DelegateCommand defined with the type of parameter which will be passed, in my case, this is the Car class, the same class as our items in the ListView.

In the constructor, I did my initialization and defined the method which will be called, that method has a parameter of the type Car.

When the user taps on one of the items in the ListView, SelectedCar (method) will be called and we can pass the data to the next view using NavigationParameters and NavigationService.

In order to retrieve the passed data we can use INavigationAware in the details view model and with the OnNavigatedTo method, access the data which is being passed.

This is my CarDetailsPageViewModel, take a look at OnNavigatedTo method.

public class CarDetailsPageViewModel : BindableBase, INavigationAware
{
    private string carTitle;
    public string CarTitle
    {
        get { return carTitle; }
        set { SetProperty(ref carTitle, value); }
    }

    private string photoUrl;
    public string PhotoUrl
    {
        get { return photoUrl; }
        set { SetProperty(ref photoUrl, value); }
    }

    public CarDetailsPageViewModel() {  }

    public void OnNavigatedTo(INavigationParameters parameters)
    {
        if (parameters.ContainsKey("selectedCar"))
        {
            Car car = parameters.GetValue<Car>("selectedCar");

            if (car != null)
            {
                CarTitle = $"{car.Make} {car.Model}";
                PhotoUrl = car.PhotoUrl;
            }
        }
    }

    public void OnNavigatedFrom(INavigationParameters parameters) { }
}

From this answer and example, you can see:

  • How to, use EventToCommand behaviour with ListView
  • Define and use DelegateCommand with passing parameter
  • How to navigate to another view and pass navigation parameter and
  • ... finally how to access the passed data.

Code and this sample you can find on my GitHub profile here.

Hope this answer was helpful for you!

Wishing you lots of luck with coding! 👋


The original question and my answer: https://stackoverflow.com/questions/67350735/xamarin-forms-and-prism-how-to-pass-data-and-navigate-to-another-view/67356514#67356514