Hi Brian, I was in your talk at Evolve 16 and that got me into Prism.
I still like it but I've got a huge issue. As the title says OnNavigatedFrom and OnNavigatedTo are not called consistently in my opinion. While I understand that this has a strong connection to the NavigationService I still think these methods should also be triggered by the Android OS back button as well as the back button of the NavigationPage. On Appearing of the Page itself is called at least but I don't want to put code into the code behind. I see this might rather be a feature request. If you got this fixed/planned I might wait for that but otherwise what do you think would be a clean solution here?
Thanks in advance Patrick
This is a known issue. The problem is that Xamarin Forms does not expose an API that I can use to hook into the hardware buttons, or the NavigationPage button events. Xamarin is aware of this need, and will be adding a method to the Application class that will enable Prism to invoke the INavigationAware methods as expected.
Thanks for clarifying this Brian. So as a workaround I think I will override OnAppearing and OnDisappearing and then cast the BindingSource to INavigationAware and route the calls through.
@chefhl - do you mind posting a little code snippet to show what you mean? I'm curious. I haven't needed to hook into these yet but I'm sure I eventually will and will want to have an idea for an approach. Thank you!
Here u go:
Create this:
public interface IPageNavigationAware
{
void OnAppearing();
void OnDisappearing();
}
Derive your ViewModel class from this interface.
In the Views code behind:
protected override void OnAppearing()
{
(BindingContext as IPageNavigationAware)?.OnAppearing();
}
protected override void OnDisappearing()
{
(BindingContext as IPageNavigationAware)?.OnDisappearing();
}
Works like a charm. BUT code in the code behind is obviously not desired - this is clearly a workaround for now. AND if your ViewModel implements INavigationAware as well as IPageNavigationAware then also OnNavigatedTo as well as OnAppearing are called.
The INavigationAware methods should only be used to handle eventually passed navigation parameters.
I have a timer on a page that animates UI on page entry and stops the animation on page exit. When the user goes back to the same page, the animation should start again, but this is not possible with the current implementation of OnNavigatedTo.
Since I'm new to MVVM, I'm also debating whether this is the job of View or ViewModel.
My first thought is you would add the INavigationAware to the Page, or just use the OnAppearing/OnDisappearing events, and kick off your animation there. Animations are always considered a view responsibility in my opinion.
@brianlagunas Has this been resolved? I'm having issues with OnNavigatedFrom not being called when clicking the NavigationBar back button. The issue is i'm using MessagingCenter to subscribe and unsubscribe so I need it to actually be called so the events don't get called more than once.
Yes, it has.
@brianlagunas Hmm. I'll have to figure out why OnNavigatedFrom isn't being called then.
Can you submit a new issue, and provide a sample that reproduces the issue. There is a chance we aren't considering a specific scenario.
@brianlagunas I'll see if I can. I'm guessing it has to do with me using the tabs. I haven't had a chance to try out version 7, so i'll play around with that first before I bother you with another issue.
@brianlagunas
In a Xamarin.Forms Prism app I've overridden MainPage.OnDisappearing, but it always gets called when the page loads. Why is that?
@weitzhandler Prism doesn't have control over the page lifecycle or when the XF events are fired. You should ask Xamarin that question.
@brianlagunas Thanks for your response.
Will implementing IDestructible or IDisposable on the views and unwire the events be of any help?
Only one way to find out :)
I ended up doing something that I think is even better, overriding Destroy in the VM, and removing all handlers from the event:
c#
public event EventHandler TimeLapsed;
public override void Destroy()
{
TimeLapsed = null;
//foreach (var handler in TimeLapsed.GetInvocationList().Cast<EventHandler>())
// Flash -= handler;
}
I want to return from OnNavigatedFromAsync() and not execute return base.OnNavigatedFromAsync(parameters); when a condition is true.
How? What should I return?
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
@brianlagunas Has this been resolved? I'm having issues with
OnNavigatedFromnot being called when clicking theNavigationBarback button. The issue is i'm usingMessagingCenterto subscribe and unsubscribe so I need it to actually be called so the events don't get called more than once.