This post is long overdue. About a year ago (July 2016) I managed to get some code into Xamarin Forms Core. This code change was necessary in order to make TinyPubSub work correctly.
TLDR;
If you call Navigation.PopToRoot() in Xamarin Forms and want to know all the pages being popped you need to cast the NavigationEventArgs to a PoppedToRootEventArgs.
var page = new NavigationPage();
page.PoppedToRoot += (object sender, NavigationEventArgs e) =>
{
// Typecast the args
var args = e as PoppedToRootEventArgs;
// Get the pages
var poppedPages = args.PoppedPages;
};
Long story
There was quite a long discussion before I got this change approved by Jason Smith and the Forms team. The most pressing issue was that we could not break the signature of the PoppedToRoot event so we ended up creating a new event args class (called PoppedToRootEventArgs) and simply passed that one in.
This of course hides the PoppedToRootEventArgs from plain sight so you need to know what you are looking for.
The internal workings of PopToRoot (the important parts) looks like this:
var args = new NavigationRequestedEventArgs(RootPage, animated);
EventHandler<NavigationRequestedEventArgs> requestPopToRoot = PopToRootRequested;
if (requestPopToRoot != null)
{
requestPopToRoot(this, args);
if (args.Task != null)
await args.Task;
}
PoppedToRoot?.Invoke(this, new PoppedToRootEventArgs(RootPage, childrenToRemove.OfType<Page>().ToList()));
The last line is the event (PoppedToRoot) and as you see we pass in PoppedToRootEventArgs as the args.
The PoppedToRootEventArgs is simply a class inheriting from NavigationEventArgs that adds PoppedPages as a IEnumerable
to the class.
public class PoppedToRootEventArgs : NavigationEventArgs
{
public PoppedToRootEventArgs(Page page, IEnumerable<Page> poppedPages) : base(page)
{
if (poppedPages == null)
throw new ArgumentNullException(nameof(poppedPages));
PoppedPages = poppedPages;
}
public IEnumerable<Page> PoppedPages { get; private set; }
}