1

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
balintn
  • 988
  • 1
  • 9
  • 19
  • Actually, i cannot reproduce your issue using a easy template. Have you generate a easy project and have a test? See [Pass data in .net Maui shell](https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation?view=net-maui-7.0#pass-data) . I could get the pass data "Name" at OnAppearing method if i set a breakpoint in this method. Or you could share more code which could help us reproduce it. – Liqun Shen-MSFT Jan 11 '23 at 07:14

2 Answers2

1

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.

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
  • That's also how it's in the documentation: https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation?view=net-maui-7.0#process-navigation-data-using-query-property-attributes – Julian Jan 11 '23 at 13:02
  • Sort of. What the doc shows is standard binding notification (OnPropertyChanged). That is needed even if it isn't a **query parameter**. No mention that you need to put **custom** logic in that same place. – ToolmakerSteve Jan 12 '23 at 00:11
0

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!

balintn
  • 988
  • 1
  • 9
  • 19