Save the page state when navigating out - windows-8

Say I have two pages, A and B.
The user can modify things on page A then navigate to page B.
When he is on page B, he clicks the "Back" button to go to page A.
Everything that has been done previously is lost.
There is a way to get the exact same state by using
this.NavigationCacheMode =
Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
But is there a way to know whether the page is opened for the first time a by using the back button?

yes it is:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
// LoadPreviousSate...
}
}
You also should've a look at ApplicationExecutionState (in OnLaunched event in App.xaml). If you navigate to Page B, Apps suspends, App continues, user navigates to Page A the NavigationMode will be New!

Related

Navigation Issue in Xamarin Forms

I need to route pages A -> B -> C -> D, once I got into D, I need to use the navigation button back to page D -> A. I am trying to implement this scenario IOS and Android in Xamarin Forms.
Please help
Your case use the Navigation.PopToRootAsync ();
Navigation.PopToRootAsync (); This method pops all but the RootPage off the navigation stack, therefore making the root page of the application the active page.
Navigation.PopAsync (); This causes the Page2Xaml instance to be removed from the navigation stack, with the new topmost page becoming the active page.
The following doc explains well about Xamarin.Forms Navigation.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/hierarchical
Inside the "D" page override the "OnBackButtonPressed" and inside the function iterate trough the pages you no longer need and remove them one by one.
Pseudo code:
protected override bool OnBackButtonPressed()
{
foreach (var page in Navigation.NavigationStack)
{
//find the pages you want to remove
Navigation.RemovePage(PageYouFound);
}
//Set new page
return base.OnBackButtonPressed();
}
You can oveeride OnBackButtonPressed Event and use Navigation.PopToRootAsync
protected override bool OnBackButtonPressed()
{
Navigation.PopToRootAsync();
return base.OnBackButtonPressed();
}

How to implement correct Back behaviour when using Frame.Navigate?

I have a Windows 10 Universal Windows Platform app with multiple pages, a main page, a list page and a details page and use the following to navigate to List page:
this.Frame.Navigate(typeof(ListPage), parameter);
When you are on the list page you can select an item which will launch a details page like so:
this.Frame.Navigate(typeof(DetailsPage), parameter);
Which works fine, the parameter is a selected Id or information then when using the Back button which on a Desktop app or Phone uses:
this.Frame.GoBack();
This always returns to the MainPage, that is when go from Main, to List to Details hitting back goes to Main, how do I get the GoBack to Go back to the previous page, it always seems to go home rather than the user expected behaviour, an ideas how to resolve this?
I’ve seen this before when you subscribe to the HardwareButtons.BackPressed event (or whatever the equivalent is in a Win10 UWP app) on a page, but then don’t unsubscribe from it. This means two event handlers get called when pressing Back, and both event handlers call Frame.GoBack().
I always subscribe to the event in the page’s NavigatedTo event, and unsubscribe in the NavigatedFrom event.
Could this be happening with your app?
If every page in your app should have the same behaviour, i.e. go back to the previous page, then subscribe to the back button event in the app class as suggested by #RoguePlanetoid in the comments:
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
The OnLaunched method would be a good place to do this. Don't forget to tell the OS to display the back button when the app is running on a desktop or tablet:
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
Then, add an event handler in the app class like this:
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
If you want different behaviour on different pages when back is pressed, i.e. ask the user to confirm losing their changes or something, then subscribe to the back button event in a pages OnNavigatedTo method (the code will be same as above), but make sure you unsubscribe in the page's OnNavigatedFrom event:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
SystemNavigationManager.GetForCurrentView().BackRequested -= this.OnBackPressed;
base.OnNavigatedFrom(e);
}

Unable to navigate backward using hardware key in a Universal App

I navigate forward using Frame.Navigate but when I press the hardware back key on my phone I end up on the start screen and not the page I just visited.
What might be wrong?
The reason behind your problem is, you are creating a Blank Page. If you're creating a blank page, you should define what the app has to do when the back button is fired.
Better, consider adding "Basic page". It will have backstack by nature. If you are navigating from the MainPage to the Basic Page and when you pressed back button at the Basic Page it will back to the MainPage.
I hope this could solve your problem!
If you want to use Blank Page in your application, you need to use like this on your page where you wanna override back button:
add this in your header:
using Windows.Phone.UI.Input;
and then in your constructor:
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
add this anywhere in your code:
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
this.Frame.Navigate(typeof(MainPage));
e.Handled = true;
}
You've probably forgotten to use the NavigationHelper included in the template of the universal app.
You should use it like this on every page:
NavigationHelper _navigationHelper;
public LoginPage()
{
this.InitializeComponent();
_navigationHelper = new NavigationHelper(this);
}

Skip displaying page if back button is pressed

I am making a Windows Phone app. If the user is using the app for the first time, it takes the person to the registration page. On successful registration, the user goes to the main page.
Suppose, the user is taken on the registration page and when the user clicks on back button without registration, he is pulled back to registration page because of the code on MainPage.xaml. The code for MainPage.xaml is as follows:
Protected Overrides Sub OnNavigatedTo(e As System.Windows.Navigation.NavigationEventArgs)
MyBase.OnNavigatedTo(e)
If Not (IsolatedStorageSettings.ApplicationSettings.Contains("IsFirstLaunchDone")) Then
NavigationService.Navigate(New Uri("/Registration.xaml", UriKind.Relative))
End If
End Sub
SO when a user is on Registration page and he taps back button, he again comes to registration page, I want the app to skip coming back to MainPage.xaml if registration is not done and exit the app.
Thanks in advance.
Add the following code to your registration page code behind.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
base.OnBackKeyPress(e);
if (UserHasntRegistered)
{
try
{
NavigationService.RemoveBackEntry();
} catch(Exception exception)
{
}
return;
}
}

Silverlight Navigation and Authentication service

I am creating a silver light application using Navigation app template. It is for internal use and hence uses windows authenticatoin. There is a dashboard page which shows couple of records filtered by logged in users id. To get the user id (which is an int) I call a web service by overriding the GetAuthenticatedUser and pass the username (from IPrincipal). This service takes some time to return the details.
When I navigate to dashboard app, it renders completely with no data because the user service is a async operation and I am not able to make the rendering wait till my GetAuthenticatedUser finishes completely. So I created a Login page which just shows a progress bar till I get the user object and then navigate to dashboard. If someone tries to access the dashboard directly by using the URL, i want them to navigate back to Login page.
So in the dashboard constructor I added the following code
if (!UserService.Current.User.IsAuthenticated)
{
MessageBox.Show("Navigating away");
Frame objContainer = this.Parent as Frame;
objContainer.Navigate(new Uri("/Views/Login.xaml", UriKind.Relative));
}
Thogh I get the message box prompt, it does not actually take me to Login page but stays in dashboard page. I also tried putting this code in OnNavigatedTo override with no luck.
I also tried using NavigationService instead of Frame as below, with no luck
if (!UserService.Current.User.IsAuthenticated)
{
MessageBox.Show("Navigating away");
this.NavigationService.Navigate(new Uri("/Views/Login.xaml", UriKind.Relative));
}
it still does not work. Does anyone know how to make some page accessible only if I have fully valid user object? if they try to access the restricted page without this, I want them to be able to redirected to Login page, how can this be achieved?
I am using Silverlight 3 Beta
Shreedhar
I finally found a way around this. In the Constructo i Hooked up the Loaded event handler and in the event handler I am navigating to a different page and it works fine now.
public Dashboard()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Dashboard_Loaded);
}
void Dashboard_Loaded(object sender, RoutedEventArgs e)
{
if (!UserService.Current.User.IsAuthenticated)
{
Frame objContainer = this.Parent as Frame;
if (objContainer != null)
{
objContainer.Navigate(new Uri("/Views/Login.xaml", UriKind.Relative));
}
}
}
This piece of code works just fine!
Shreedhar