How to pass navigation properties in Maui?

1.4k Views Asked by At

I have a Maui app, with an item collection view and an item detail view. When an item is tapped in the collection view, I'd like to navigate to the detail view. I use Maui Shell navigation. The code comes from a Xamarin app, where it used to work. The route is registered in AppShell.xaml

In the tap event handler on the collection page code behind

        async void OnItemTapped(ItemViewModel itemVM)
        {
            string route =
                $"//{nameof(ItemPage)}?{nameof(ItemPage.Id)}={itemVM.Id}";
            await Shell.Current.GoToAsync(route);
        }

In debugging, I can verify that the contents of variable route are as expected.

Details page code behind (redacted to relevant bits):

    [XamlCompilation(XamlCompilationOptions.Compile)]
    [QueryProperty(nameof(Id), nameof(Id))]
    public partial class ItemPage : ContentPage, IDisposable
    {
        /// <summary>Navigation property to pass Id value.</summary>
        public string Id { get; set; }

        public TablePartyPage()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            
            // Id is populated by navigation.
            string id = TablePartyId.FromUrlQueryValue(Id);  /* Problem: Id is null here */
            var viewModel = new ItemViewModel(
                ...
            );
            BindingContext = viewModel;
        }
    }

On executing GotoAsync() the ItemPage constructor, then ItemPage OnAppearing() is executed, however, the navigation property is not populated.

What am I missing?

Environment is:

  • Visual Studio 2022, v17.4.3
  • Maui v7
2

There are 2 best solutions below

0
balintn On BEST ANSWER

It seems like it was a navigation issue, mentioned in this related question: How to register a non-shell-visible navigation route in Maui Shell?

Fixed the non-shell navigation as suggested in the first comment there and navigation property was populated.

Thank you for all your suggestions!

2
ToolmakerSteve On

Wow, Maui Navigation doc doesn't seem to specify when query parameters are applied. It they aren't applied by the time OnAppearing is called, that's not a good internal design.

You could add an issue at github maui issues.

Work-around is to remove code from OnAppearing, put code in property setter(s), to apply property changes. Something like:

public string Id {
  get => id;
  set {
    if (SetValue(ref id, value))   // Might be a different method, depending on MVVM implementation.
    {
      ... use Id here ...
    }
  }
}
private string id;

Seems like a PITA, if there are multiple properties being passed, and all of them need to be set before the "use Id" code runs. In that case, have all setters call a method that does nothing until all properties have expected value.