Home > Mobile >  Passing a property between pages using the Shell, Property Binding, and ViewModels on .NET MAUI
Passing a property between pages using the Shell, Property Binding, and ViewModels on .NET MAUI

Time:12-01

On a MAUI app, I'm trying to pass a value from one page to another through their respective ViewModels, but it's not working and for the life of me I can't figure out why.

Source VM:

[RelayCommand]
public async Task GetAdvertDetailsPageAsync(int advertId)
{
    await Shell.Current.GoToAsync($"{nameof(AdvertDetails)}?AdvertId={advertId.ToString()}");
}

Destination VM:

[QueryProperty("AdvertId", "AdvertId")]

public partial class AdvertDetailsVM : ObservableObject
{
    [ObservableProperty]
    public string advertId;

    public AdvertDetailsVM(IMyHttpClient httpClient)
    {
        LoadAdvertAsync(Convert.ToInt32(AdvertId));
    }

Destination ContentPage:

public partial class AdvertDetails : ContentPage
{
    public AdvertDetails(AdvertDetailsVM vm)
    {

        InitializeComponent();
        BindingContext = vm;
    }
}

The parameter advertId on the GetAdvertDetailsPageAsync on the source page has a value, the destination page gets called, and the ViewModel gets injected just fine, but the AdvertId property on the destination comes up empty and I can't figure out why. For the record, I'm following this tutorial

Thanks in advance

CodePudding user response:

I figured it out. It's actually working as intended. The problem was that I was checking the property while the constructor was executing, and it turns out it doesn't actually set it until the page finished "navigating to".

So I added this to my destination page:

protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
    base.OnNavigatedTo(args);
    _vm.LoadAdvertAsync();
}

Calling the LoadAdvertAsync() method from here instead, since at this point the property I was trying to pass (AdvertId) has been set and can be worked with (the property is used inside this method and is not a parameter of it anymore).

CodePudding user response:

The way you want to deal with your problem is this:

public partial class AdvertDetailsVM : ObservableObject, IQueryAttributable

You implement method of that interface, that executes when you get your query:

public void ApplyQueryAttributes(IDictionary<string, object> query)

Inside this method you access your data, using this:

AdvertId = query["AdvertId"] as string;
  • Related