Search code examples
xaml.net-maui

.Net Maui Shell Navigation - Is it possible to pass a Query Parameter and Auto Populate a Page?


I need to auto populate a Page by passing a Shell Navigation Parameter to a ViewModel/Method and call a Service to return a single record from a Web Service. Essentially a drill-through page. My issue is that I need to call the data retrieveal command, "GetFieldPerformanceAsync" (note [ICommand] converts this to "GetFieldPerformanceCommand") from the "To" Page's code-behind from within OnNavigatedTo. This is required since the Shell Navigation Parameter is not set in the ViewModel until the Page is loaded. I'm currently unable to make the Command call from OnNavigatedTo and need advice on how to accomplish this.

Thanks!

Code behind the Page:

public partial class FieldPerformancePage : ContentPage
{
   public FieldPerformancePage(FieldPerformanceViewModel viewModel)
   {
       InitializeComponent();
       BindingContext = viewModel;
    
       //works with parameter hard-coded in ViewModel
       //viewModel.GetFieldPerformanceCommand.Execute(null);
   }

   FieldPerformanceViewModel viewModel;
   protected override void OnNavigatedTo(NavigatedToEventArgs args)
   {
       base.OnNavigatedTo(args);
       //this does not work 
       viewModel.GetFieldPerformanceCommand.Execute(null);
   }
}

ViewModel

namespace TrackMate.ViewModels;

[QueryProperty(nameof(FieldAssignedWbs), nameof(FieldAssignedWbs))]
public partial class FieldPerformanceViewModel : BaseViewModel
{
   [ObservableProperty]
   FieldAssignedWbs fieldAssignedWbs;

   [ObservableProperty]
   FieldPerformance fieldPerformance;

   FieldPerformanceService fieldPerformanceService;

   public FieldPerformanceViewModel(FieldPerformanceService fieldStatusService)
   {
       Title = "Status";
       this.fieldPerformanceService = fieldStatusService;
   }

   [ICommand]
   async Task GetFieldPerformanceAsync()
   {
       if (IsBusy)
           return;
       try
       {
           IsBusy = true;

           int wbsId = fieldAssignedWbs.WbsId;

           var fieldPerformanceList = await fieldPerformanceService.GetFieldPerformanceList(wbsId);

           if (fieldPerformanceList.Count != 0)
               FieldPerformance = fieldPerformanceList.First();
       }
       catch (Exception ex)
       {
           Debug.WriteLine(ex);
           await Shell.Current.DisplayAlert("Error!",
               $"Undable to return records: {ex.Message}", "OK");
       }
       finally
       {
           IsBusy = false;
       }
   }
}

Solution

  • I believe I figured it out...

    By adding ViewModel Binding within the OnNavigatedTo method in the "DetailsPage" Code Behind, a Command Call can be made to the Page's ViewModel to execute data retrieval method after the Shell Navigation Parameter (object in this scenario) passed from the "Main" Page has been set. Note a null is passed since the Query Parameter is sourced from the ViewModel. If you are new to .Net Maui, as I am, I recommend James Montemagno's video on .Net Maui Shell Navigation.

    namespace TrackMate.Views;
    
    public partial class FieldPerformancePage : ContentPage
    {
       public FieldPerformancePage(FieldPerformanceViewModel viewModel)
       {
          InitializeComponent();
          BindingContext = viewModel;
       }
    
       protected override void OnNavigatedTo(NavigatedToEventArgs args)
       {
           FieldPerformanceViewModel viewModel = (FieldPerformanceViewModel)BindingContext;
           viewModel.GetFieldPerformanceCommand.Execute(null);
    
           base.OnNavigatedTo(args);
       }
    }