I am currently trying to implement a navigation scheme that closely resembles that of the Internet Explorer app on Windows Phone 8.
The IE app can have multiple tabs that the user can switch between. Each of these tabs has its own history. Hitting the Back Button on the phone takes you to the previous page in that tab's Navigation history (Not the PhoneApplicationFrame.BackStack
). If there are no previous pages, the back button takes you to the previous opened tab or, if none, exits the app.
Why this is troubling me
Application.RootVisual
can only be set once. So you can't have two PhoneApplicationFrames, each with its own BackStack, to swapRootVisual
between the two.You cannot traverse the BackStack (it is a Stack, after all). Can only call
GoBack()
. CallingGoForward()
will throw an Exception.PhoneApplicationFrame.GoBack()
removes entries from the BackStack which can only be added again through thePhoneApplicationFrame.Navigate(...)
method. So, manipulating the BackStack is a no-go.
Bright Ideas
Keep a
Dictionary<enum, List<string>>
which is updated with each call to a customNavigationService.Navigate(tabTypeEnum, uriString, params)
. This will keep the Navigation history for eachtabType
, allowing us to possibly Navigate through the current Tab's history when theBackKeyPress
event is handled. Bad thing is, callingNavigate(...)
to go to previous pages (instead ofGoBack
) will add to the BackStack. So requires maintenance that hurts my brain right now.Create a custom
NavigationAwareTabPage : PhoneApplicationPage
, which keeps track of its own navigation history and fakes navigation by animating a transition when itsContent
is changed. The only time we call a trueNavigate
is when we switch from one tab to another. (I think this is what the IE app does.) And theBackKeyPress
would have to look like below.
This:
void RootFrame_BackKeyPress(object sender, CancelEventArgs e)
{
var rootFrame = sender as PhoneApplicationFrame;
if (rootFrame.CanGoBack)
{
// Get the NavigationAwarePage
var navAwarePage = rootFrame.Content as NavigationAwareTabPage;
if(navAwarePage.CanGoBack())
{
// This method "navigates" to the next page
// by changing the navAwarePage.Content
navAwarePage.GoBackToPreviousPage();
e.Cancel = true;
}
}
}