gfmoore
gfmoore

Reputation: 1226

.Net maui: MVVM How to catch a return from a different page using shell navigation

I have set up a mainpage - detail page navigation using the Shell GoToAsync navigation

[RelayCommand] 
public async void SelectionChanged() //Friend friend
{
    if (SelectedItem == null) return;

    Friend f = SelectedItem;

    Console.WriteLine($"Selection made {f.FName} {f.LName}");

    //navigate
    var navigationParameter = new Dictionary<string, object>
    {
        { "Friend", f }
    };
    await Shell.Current.GoToAsync(nameof(DetailPage), true, navigationParameter);

    //remove selection highlight
    SelectedItem = null;
}

This works. However, I am at a loss as to how to capture the return from the detailpage in my mainpage as I need to do a refresh of my CollectionView and underlying sqlite datastore.

I have followed the Gerald Versluis video at https://www.youtube.com/watch?v=pBh5SXVSwXw for the most part.

Any ideas?

Many thanks, G

Upvotes: 5

Views: 7435

Answers (5)

Roberto Oropeza
Roberto Oropeza

Reputation: 13

I did it as Isidoros Moulas wrote.

But for it to work for me to, send the MainPage object (the source page) to the DetailPage and then return the value, I did the following:

Note: I use model navigation.

In my MainPage

Declare as property where we are going to save the returned value

public string value {get; set;}

Send as a parameter the instance already created with the model when I change the page like this:

await Navigation.PushModalAsync(new DetailPage(this));

In DetailPage,

I declared a property of type MasterPage

private MasterPage master_page;

and in constructor declated the MainPage object as a parameter.

 public ReaderCodesCamara(MasterPage masterPage)       
{
    InitializeComponent(); 
    master_page = masterPage;
}

And for return the value to the MasterPage:

master_page .value = "IDidSomething"; 
await App.Current.MainPage.Navigation.PopModalAsync();
WeakReferenceMessenger.Default.Send(master_page);

Greetings

Upvotes: 0

user22504825
user22504825

Reputation: 1

You can catch the action of returning, using the shell. Explained at the end of this documentation: https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/navigation

You can catch the return action, by using the shell BackButtonBehavior and creating a command passing parameters, the same way you did to navigate to detail page. Passing the collectionview to keep it updated.

Upvotes: 0

Isidoros Moulas
Isidoros Moulas

Reputation: 697

MessagingCenter has been deprecated in .NET 7 and replaced with WeakReferenceMessenger in the CommunityToolkit.Mvvm NuGet package. For more information, see docs

At your master page:

public class MessageModel() {
    public string Message {get;set;}
}

public MasterPage() {

   ...

   WeakReferenceMessenger.Default.Register<MessageModel>(this, (r, m) =>
   {
     // do something, reload view 
   });
}

and at your detail page when you go back:

MessageModel messagemodel = new() {
    Message = "IDidSomething"
};
WeakReferenceMessenger.Default.Send(messagemodel);

Upvotes: 0

gfmoore
gfmoore

Reputation: 1226

As it turns out this was not as hard as it might have seemed. @ToolmakerSteve pointed out a solution, but I didn't understand it at the time. The solution is to simply use the MessagingCenter approach. The documents https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/messagingcenter aren't very clear on usage, but adapting the note in https://codemilltech.com/messing-with-xamarin-forms-messaging-center/ I did the following

In my detail page ViewModel and the button for returning to the main page (not the Back button which I haven't captured yet). (Using MVVM helpers version 8.0.0.0 Preview 4 (not 7, but could be adapted),

[RelayCommand]
public async void ReturnMainPage()
{
  MessagingCenter.Send(new MessagingMarker(), "IDidSomething");
}

and in the MainPageViewModel in the constructor

public MainPageViewModel()
{
  ...
  MessagingCenter.Subscribe<MessagingMarker>(this, "IDidSomething", (s) => {
    //do something in response to the detail page changing something
  });
  ...
}

Hope this helps someone in the future. G.

btw can someone tell me what the "this" is referring to? The page? What else could be put here as "this" might not be appropriate depending on the location of the code?

PS You can pass objects using this as well, see my question on .Net Maui: How to read/write (get/set) a global object from any content page (MVVM)

Upvotes: 1

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13863

but I'm needing some other event to be raised when I click on some button and navigate back.

If you want to do something while navigating back, you can use BackButtonBehavior to achieve this.

And if you want some other event to be raised while clicking on some button and navigating back, you can try the following code :

 await Shell.Current.GoToAsync("..");

And backwards navigation with ".." can also be combined with a route:

 await Shell.Current.GoToAsync("../route");

For more,you can check: Backwards navigation .

Upvotes: 0

Related Questions