0

I'm having trouble trying to figure out why I can't get a navigation property to pass to my page in Maui. I do understand that I shouldn't be able to see the property value in the constructor of the navigated to viewmodel but, even when I try to view the object in the actual navigated to page-behind code, it still appears null...

Passing the navigation property [MainViewModel.cs]

[RelayCommand]
async Task ShowPhotoDetails(PhotoDetailsFacade PhotoDetails)
{
    Dictionary<string, object> navigationParameter = new Dictionary<string, object>();
    navigationParameter.Add(nameof(PhotoDetailsFacade), PhotoDetails);
    await Shell.Current.GoToAsync($"PhotoDataPage", navigationParameter); //navigation parameter is filled here, can see properties when debugging         
}

PhotoDataPage is bound to a viewmodel... and has a binding to the viewmodel... [PhotoDataPage.xaml]

<ContentPage xmlns="[http://schemas.microsoft.com/dotnet/2021/maui](http://schemas.microsoft.com/dotnet/2021/maui)"
xmlns:x="[http://schemas.microsoft.com/winfx/2009/xaml](http://schemas.microsoft.com/winfx/2009/xaml)"
xmlns:viewmodel="clr-namespace:FishSnapData.ViewModel"
x:DataType="viewmodel:PhotoDataViewModel"
x:Class="MyProject.PhotoDataPage"
Title="PhotoDataPage">

...

<VerticalStackLayout BindingContext="{x:Type viewmodel:PhotoDataViewModel}"/><Image Source="{Binding PhotoDetails.FilePath}" HeightRequest="300" />

The viewmodel should receive the parameter... [PhotoDataViewModel.cs]

//[QueryProperty(nameOfPropertyThatWillRecieveTheData, parameterID (e.g. if there are multiple passed, this is the key in the dictionary))]
[QueryProperty("PhotoDetails", nameof(PhotoDetailsFacade))]
public partial class PhotoDataViewModel : ObservableObject
{
    [ObservableProperty] //adds all the inotifyproperty goo needed for databinding and onchanged events
    private PhotoDetailsFacade photoDetails;
        
    public PhotoDataViewModel()
    {           
    }...

Finally, the page hooks up the viewmodel. It is at this point that I think I should be able to view the properties of the PhotoDetails object but, they are still null [PhotoDataPage.xaml.cs]

public partial class PhotoDataPage : ContentPage
{
    public PhotoDataPage(PhotoDataViewModel Vm)
    {
        InitializeComponent();
        BindingContext = Vm; //browsing, the PhotoDetails object is still null here
    }

Any suggestions to help me figure this out will be very much appreciated. Thanks

beeker
  • 780
  • 4
  • 17
  • photoDetails is a field. PhotoDetails is a property. Changing fields does not call any code. Changing property does. I suggest that you do this here: https://stackoverflow.com/a/75323798/6643940. Place a break point, and see it work. If you have a problem implementing it, just ask. Forget about those annotations. – H.A.H. Apr 24 '23 at 04:52
  • @Liquin my problem is *solved but unfortunately not by any of the comments/answers here. Honestly, I'm not sure exactly what it was that made it start working again. Without making any code changes to what I show above, it started working after I debugged on an android emulator (previously I had only been doing windows debugging). I suspect debugging in something different caused parts of the code to build again that weren't previously getting cleaned/built? – beeker Apr 27 '23 at 22:28
  • Glad you solved it! But I don't think debugging on a different platform makes any difference. – Liqun Shen-MSFT Apr 28 '23 at 02:25

1 Answers1

0

There are two approaches to receiving navigation data:

  1. Process navigation data using query property attributes
  2. Process navigation data using a single method

You may use the second approach, as you want to pass the data to viewmodel (not code behind) which represents the BindingContext of the PhotoDataPage.

You may try the following code (for PhotoDataViewModel)

public partial class PhotoDataViewModel : ObservableObject,IQueryAttributable
{
    public PhotoDataViewModel()
    {

    }

    [ObservableProperty] //adds all the inotifyproperty goo needed for databinding and onchanged events
    private PhotoDetailsFacade photoDetails;

    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
        PhotoDetails = query["PhotoDetailsFacade"] as PhotoDetailsFacade;
    }
}

Hope it works.

Liqun Shen-MSFT
  • 3,490
  • 2
  • 3
  • 11