I have an app I'm working on where the user gets navigated two pages deep, meaning:
Select stuff, click next -> select stuff, click next -> results
On the results page, I'm doing a Navigationservice.Navigate() back to MainPage.xaml but now the user has the ability to hit the back button which can break some things in the app. How can I clear that buffer of pages available? Any way to for Navigationservice.canGoBack return false even if it's true? If the buffer can't be cleared, the is there a method which will restart the app to get the user back to the MainPage.xaml without having any navigation history?
Thank you,
Nick
Here's a few references for solutions to clearing the back stack.
Want to "reset" an app but how to deal with backstack pages?
Removing a page from the navigation stack
Can the navigation history be cleared
Alternatively, consider Peter Torr's suggestions on handling navigation scenarios.
Introducing the concept of “Places”
Redirecting an initial navigation
Related
I'm running into a weird issue where after my app has stopped responding to Frame.Navigate requests after the app has been snapped. I am writing a search app with 3 pages: a query entry page, a results page, and a result detail page.
Running the query successfully uses Frame.Navigate(typeof (Results), QueryBox.Text); to open the results page (Descendant of LayoutAwarePage) in both snapped and unsnapped states.
When the search is run from the unsnapped UI, I am able to click on a result and navigate to the details page. When the search is run from the snapped UI, however, I am unable to actually navigate to the correct page. After the snapped results page has been loaded it appears that any sort of navigation is completely impossible. Clicking the back button does not return to the query page (although it does appear to be affecting the navigation stack, as the back button does go away).
Through debugging, I've uncovered the following information:
The correct button handler code is still being called. Snapped view and full view are executing the same exact code to launch the details page (Frame.Navigate(typeof (DetailPopup), pb.PodOwner);, where DetailPopup is the page, and pb.PodOwner is the data context for the page).
The constructor for the DetailPopup page is actually being called, but the page is still not loading.
After restoring the snapped page to the unsnapped state, the effect of being unable to navigate persists.
After commenting out all changes applied in <VisualState x:Name="Snapped"> of the Results page the problem persists
I've read that there are issues with Frame.Navigate being called from OnNavigatedTo, but all these interactions are happening well after that method has completed. Are there other similar caveats for other methods / events?
If there's any code specifically that you'd like to see I'd be happy to post it, but I'm not sure where the offending issue is and posting the entire page source would be kind of overwhelming ;)
I recently ran into weird bug in Bing map control. In short, if the connection is poor and you press the hardware back button on page with map while the map is still loading some tiles, the navigation process hangs up (some times up to 10 or even more seconds). And in case when the time is more than 3 seconds the app will be "a little" not user-friendly and will not meet the technical certification requirements (5.1.3).
To repeat the bug you can create the app with two pages. First one with button to navigate to the second page. And the second page with just map control with high ZoomLevel (more than 14 for example). After the app launches, you navigate to the second page and move map to some unloaded area and then (without waiting for the download to complete) press the hardware back button. And also you somehow must "create poor" connection (in my case, simply disconnecting the device from the computer is enough).
And does anyone have any idea why this occurs and how to workaround it?
EDIT: The same bug can be observed in the Foursquare application for wp7 - if you go to the page where the place is shown on the map in full screen, then slide the map into an unloaded region and press the hardware button back.
It seems that the problem is in the Bing Map Control.
Hide the Maps control using the Visibility first, before you navigate out of the page. That way the control will become inactive and memory consumption of the page will decrease, thus allowing to switch pages faster.
I have an application which displays a disclaimer page when it is first run. Once you select Accept or Deny you never see the page again.
However, when you press the back key attempting to close the application after the first run, you go back to the disclaimer page, then if you hit it again, back to the main page and then again to exit.
This only happens the first time the application is run, but I would like to have the application ignore the disclaimer page when the back key is pressed and exit the application.
Other than forcing an unhandled exception error to close the app, are there any other options?
Thanks in advance.
Solution: Add the below NavigationService.RemoveBackEntry(); in my main page.
private void PhoneApplicationPage_Loaded_1(object sender, RoutedEventArgs e)
{
NavigationService.RemoveBackEntry();
NavigationService.RemoveBackEntry();
}
I am sure there is a more elegant way to do it, but I was in a hurry, so I implemented it in a following way.
I have a static global enum that stores the last page I was on. Assuming you have pages called pgDisclaimer and pgMain.
In the OnNavigatedTo event of the pgDisclaimer page, check to see where the control came from. If it came from pgMain, just execute NavigationService.GoBack() and you'll be out of the application and the user will never actually see pgDisclaimer page (not even a flicker).
Edit: Found the more elegant way. In Mango, you can use the horribly named NavigationService.RemoveBackEntry() method.
You should display the Disclaimer as a popup rather than a page, that way you don't have to worry about navigation and backstack issues. I saw this mentioned in a Channel 9 video:
Windows Phone: building apps that customers love, end to end
The specific part in the presentation that covers this is at around 26:20. He's discussing a login page that prevents a user from navigating back out of the app, but the concept is similar.
Also, from this MSDN Blog Post:
I forgot the #1 piece of advice regarding EULA / Login screens - don't make them into pages. If you instead make them Popup controls you can show or hide them at any time (on first navigation; when the user hits a "protected" part of the app; after a time-out; etc.) and they don't consume a slot in the backstack. This should cover the majority of cases.
I'm writing a web-based application for internal use within the business where I work. It's a fairly complex application, with a lot of forms that will allow the user to view and enter data, which once saved will be stored in a database.
One thing I'm anxious to avoid is allowing a situation to exist where a user might enter large amounts of data in the browser, and then (either deliberately or inadvertently) navigate off the page without saving the changes. To this end, I have already implemented an entry page which opens up a new browser window in which there are no navigation controls at all; only what is provided on the web pages themselves.
However, there are two potential ways in which a user could still lose data:
The browser Close button is still enabled, and a user could potentially lose work by clicking it inadvertently. I can probably live with this, as it falls at the extreme end of helping the user not to shoot himself in the foot.
In Internet Explorer (and, apparently, in Firefox) the Backspace button works like a Back button. I only discovered this accidentally, and have as yet been unable to find a simple way of stopping this behaviour. This is potentially a problem, as an inadvertent use of the Delete key (e.g. having positioned the cursor in a read-only textbox, or when the cursor isn't on any particular field in the page) will navigate off the page.
What I would like to do, as a minimum, is prevent Backspace from navigating off a page if that page has any user-writable fields on it and any of those fields have been changed by the user since the form was loaded. Ideally, I would like to disable this particular use of the Backspace key completely, while the user is logged into this web application. The two possible ways that I can think of, for achieving this, are: (1) clear the browser's history as each page is loaded, or (2) trap the Backspace key and only allow it to work if the cursor is positioned within a field whose text can be changed (e.g. a textbox).
Can anyone suggest how I could achieve either of these things? The solution needs to be programmatic, rather than something that has to be manually configured on every browser in the company.
Instead of blocking* functionality that your users have learned to expect in their daily activities at work and at home, why not work with it? Make the "back" button actually take them to the previous screen as expected, and use AJAX to silently save the form as they fill it out (say, every 5 or 10 seconds), so when they return to the form you can check to see if they already have partial, unsubmitted values saved and reload them.
This approach aligns with the realities of web-based applications and delights users if implemented well. An alert that says "you did something wrong" just frustrates users and makes them trust your application less. Remember - users almost never do the wrong thing. It's our applications that aren't aligned with usage.
* more like trying to block functionality. As you've discovered, people who designed the interwebs and web browsers never really intended for site developers to totally disable moving back and forward in the navigation history.
What about something like this? You can ask them if they are sure before they leave.
var changes = false;
window.onbeforeunload =
function()
{
if (changes)
{
var message = "Are you sure you want to navigate away from this page?\n\nYou still have unsaved changes.\n\nPress OK to continue or Cancel to stay on the current page.";
if (confirm(message)) return true;
else return false;
}
}
You should look at the Javascript's window.unload event.
This is fired when the use tries to leave the page. You can't totally stop them leaving the page, but you can give them a chance to cancel.
try this
window.onbeforeunload() {
return "Are you sure you want to navigate away?";
}
I know about tombstoning stuff any how to save the states of your application but my question is this regarding states.
Let's say I have a page that have 5 buttons. Whenever I click a button the button can be either visible or hidden. How do I save the current state or the saved state of my page? Let's say if I exit my application and loaded the 5 buttons again one button should be hidden.
I tried saving a variable state value in an IsolatedStorageFile and retrieve it when the Page is loaded in loaded event but I figured out that it's too tedious for the processor to do a lot of things just for saving a state.
Another solution I thought of is when the Loaded event is fired, I will statically declare an if else statements and manually declare the Visibility of the button.
Is there any other way?
Are you trying to do the same thing when the page/app is exited normally and when it's tombstoned? The default expected behaviour is that when launching the app after exiting (via the back button) the app will be in it's default state. When returning from a tombstoned state the app should (as far as is appropriate) be displayed to the user in exactly the same way as when the page/app was tombstoned.
Of course you may have differing needs but I wanted highlight the standard behaviour.
If you want to store state while tombstoned, the convention is to use the OnNavigatedFrom and OnNavigatedTo events to store details in the State object.
There is a good example of how to do this on MSDN: How to: Preserve and Restore Page State for Windows Phone
If you want to preserve state across all executions of your app then you will need to use IsolatedStorage to store the details in a persistent location. Where and when you read and write the data will depend on where the data you need to persist is located.
If it's at an applicaiton level you may be able to use the application level events (Launching, Activated, Closing & Deactivated). If you have state data at page level it's probably be better to do it in the page level (Loaded/Unloaded or NavigatedFrom/To as appropriate).
If you want to store state across all executions of the application you probably need to look at both of the above options.
The System.IO.IsolatedStorage namespace is fine for this kind of behaviour, check it out here
Also check out this article on how to do what you are asking.
Saving Applications States