I've got an intermediate "Loading" page for my game: I send them there and it has "Loading..." text that displays while the rather hefty game page loads up:
private void OnLoaded(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
try
{
NavigationService.Navigate(new Uri("/GamePage.xaml", UriKind.Relative));
NavigationService.RemoveBackEntry();
}
catch (InvalidOperationException)
{
}
});
}
Then when you hit the back button you go to the main page rather than back to the loading screen. There's no other logic on the page.
However I just got a store submission declined: apparently on the Samsung Focus and Odyssey the navigation entry for the loading page didn't get removed, and the user is sent back to the loading page when they hit the back button, rather than back to the main menu. I'm guessing RemoveBackEntry failed.
This looks like it should work, I can't reproduce the error and I don't have a Focus or Odyssey to work with. Does anybody know what might be going wrong?
I think you should replace:
NavigationService.RemoveBackEntry();
with:
while (NavigationService.CanGoBack)
{
NavigationService.RemoveBackEntry();
}
You have to remember that NavigationService.Navigate will perform the navigation asynchronously. So when you call NavigationService.RemoveBackEntry(), the current page might not yet be on the BackStack.
To fix that, call RemoveBackEntry in OnNavigatedTo of GamePage.
Related
Project and problem explanation
In my case I have a page which instructs the user how to move a certain machine. This page is supposed to be a modal page since the page should not be navigated away from without performing or completely canceling the action.
I have a mainpage with a listview which opens the details page of any of the items contained in the listview on click through the onSelect method:
Navigation.PushAsync(new FooPage(string Name)); /* gets called in the
onSelect method if selection is not null*/
The model is retrieved within the details page's viewmodel after passing the name to it and then using a model manager injected into the viewmodel with Unity to retrieve it.
-- we now both have a mainpage and detailspage on the stack which of only the detailspage has a backbutton --
On the detailspage we have a button called "Teach" with a x,y,z field next to it after clicking it this method gets called:
private async Task Button_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new ManualTeachPage());
}
which then, as it should, creates the page but then for some reason decides to add a back button to it:
Debugging and Research
This behavior is not visible on Android which does not have a visible back button or navigation bar on this page but does have a backbutton on the Details-page as well.
I have used modal pages before but I have never seen this kind of behavior, I have tried using the Navigation property of the Application.Mainpage itself which resulted in the exact same result except for one case.
I thought it might have something to do with me switching out the Application.Mainpage at one point(there is a stack of tutorial pages the user has to go through), seems like calling the pushModalAsync one line AFTER setting the new mainpage then it DOES push the page as a modal page and performs like one (without a back button) but does not do so after this point.
No bug reports on Bugzilla about this either as far as I have seen, neither have I found anything on the internet about this particular problem.
Note that when clicking the back button on the teachPage it returns to the detailspage. When the teachPage gets pushed it does actually get pushed onto the ModalStack.
update 1
Checked again if the modal page which I was talking about was the only modal page on the modal Stack, it was. NavigationPage.SetHasBackButton(this, false); does not seem to work either as suggested by Diego Rafael Souza.
update 2
I thought I would temporarily disable the backbutton by using the onBackButtonPressed within the teachpage until I had found a solution. Turns out this doesn't work for UWP anymore, this method does not get called anymore on this page or any page for that matter. It does work for the Android Hardware button though.
update 3
I tried using:
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
AppViewBackButtonVisibility.Collapsed;
This does hide the backbutton on UWP but for some reason #if WINDOWS_UWP doesn't work at all. If I do this without the #if the program won't build for Android. No solution yet, not only this but when using this fix the other pages still had the onBackButtonPressed method disabled.
update 4
after updating to the newest version of xamarin forms the OnBackButtonPressed started working again. The backbutton still appears on the page but I now have disabled it.
Recreating the problem
I recreated the problem in this small test project:
https://www.dropbox.com/sh/6btsud3uvw503ee/AAAiaGb3TwhMrZMJb2j-rd36a?dl=0
In your function Button_Clicked() in your example, in page DetailPage, where you call your Modal, right after calling PushModalAsync(new TeachPage());, use:
NavigationPage.SetHasNavigationBar(this, false);
NavigationPage.SetHasBackButton(this, false);
My guess is when you tried using the above SetHasBackButton, you were doing it on the Modal itself, but the back button you were actually seeing came from your DetailPage.
Once you add this, the modal pops up, and the back button disappears. If you set a "Back" button on your modal in order to close it, you can easily get your NavBar and BackButton back in your DetailPage by adding in an OnAppearing() Function in your DetailPage code-behind like so:
protected override void OnAppearing()
{
base.OnAppearing(); // do the usual stuff OnAppearing does
NavigationPage.SetHasNavigationBar(this, true); //get your navbar back
NavigationPage.SetHasBackButton(this, true); //get your back button back
}
I have a home page or landing page in my windows phone c# based app where user enters login details and upon successful login user is redirected to page2 . Here the user will see a list box with few items . Upon selecting an item from this list box a new page called "Threadx" opens.(where x is the each page that opens upon clicking the x item in the list box)
While user is on this Thread page "Threadx" he may receive the toast notifications and the thread gets updated with new replies or answers on that thread.
But When user clicks on back button the "ThreadX" page doesn't get closed and instead it goes to its previous state where it has less number of messages , and so on until the app gets closed.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode == NavigationMode.Back)
{
return;
}
}
I would like to know if this "Threadx" page can be closed upon clicking back button without affecting other "Threadx+1","Threadx+2"..."Threadx+n" pages.
Any help would be really appreciated.
Normally windows keeps the pages on it's stack when you leave a page and navigate to another page. If you want to navigate to the previous page on pressing the Back Button you can do following things:
Add following line to OnNavigatedTo method:
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
Add definition for HardwareButtons_BackPressed method:
private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
e.Handled = true;
if (Frame.CanGoBack)
Frame.GoBack();
}
Don't forget to add Windows.Phone.UI.Input to the namespace list.
The other way I got it worked was using the below code in the onnavigateto method in my "thread" page and it worked for me. Let me know if there is an elegant way of doing it or better way of doing it .
if (e.NavigationMode == NavigationMode.Back)
{
NavigationService.Navigate(new Uri("/View/Page2.xaml", UriKind.Relative));
}
I am using a web-browser in my windows phone 7 application.
I just want to know that how to handle its back and forward navigation just like any desktop browser.
And also how to block a particular navigation.
I referred here and many others but couldn't find anything working for me.
Please help.
You can cancel navigation by handling the OnNavigating event
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
//cancel navigation
e.Cancel = true;
}
To go back, you can execute javascript on the page.
webBrowser.InvokeScript("eval","history.go(-1)");
and move forward:
webBrowser.InvokeScript("eval","history.go(1)");
If eval is blocked on the page, this site might be useful for alternatives. Don't forget to set webBrowser.IsScriptEnabled to true.
To make it work like a desktop browser you can implement a stack.
You will put two buttons back and forward. As the user navigate to next URL in browser you push them into history stack and when he wants to get back by pressing back button you navigate to the first url in the history stack programmatically and pop it up from the history stack so he can navigate back till stack has some URLs in it. Similarly for forward you push URLs into forward stack as he navigates back and and whenever he presses forward button you navigate to first element in forward stack and pop it up and so on till you have urls left in forward stack. Once he navigates to some url which is not navigated from forward stack by you then you empty the forward stack and fill it again when he moves back.
This way you can even show history urls in a list or however you like.
About navigation cancel, here is the code from the link to question in the comments under your question, it should work.
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
//cancel navigation
e.Cancel = true;
}
Previous answer will work, but you can make a workable solution even simpler, since the WebBrowser control has an internal navigation stack.
Add forward and back button controls to your UI. In the action routine for each of them:
private void forwardButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
WebBrowser editWB = sender as WebBrowser;
if (editWB != null && editWB.CanGoForward)
editWB.GoForward();
}
You can get fancier: in the WebBrowser.LoadComplete event (not the FrameworkElement.Loaded event), you could test .CanGoForward and .CanGoBack and selectively enable or disable the buttons appropriately.
I tried to implement the idea proposed by BobHy but failed as in my WP7 / VS2010 Express I did not find the method CanGoForward for WebBrowser. I am using it inside of a canvas in user control which might impact the experience.
However, I found a straight forward detailed example at http://developer.nokia.com/community/wiki/WebBrowser_Control_Techniques_in_Windows_Phone implementing a stack as suggested by Parveen that works for me fine.
For a windows phone 8 app I'm developing, I had to load some data at the starting of the app. For that matter I designed a page called SplashScreen.xaml that loads the data and after all the loading is done I navigate to the MainPage.xaml using:
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
Now when the user is in the main page and taps the back button on the phone instead of going out of the app(which is the default gesture) goes back to the SplashScreen.xaml, making them unable to go out of the app(except for taping the start button which take's the app to background) and of course giving them a bad impression.
The question is How to prevent going back to the previous page
Thank you all.
Just clear the backstack when landing on MainPage:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
while (NavigationService.RemoveBackEntry() != null);
}
Here is my button:
protected void Button_Click(object sender, EventArgs e)
{
...//things it does
}
When I update the page, google chrome (for ex) asks me if I want to redo the action above. Lay people will press continue and the action is gonna happen, but it cant happen. How can I clear this action from "memory" for it don't happens again?
thanks a lot!
After you have done your processing in the button click event you can then do a Response.Redirect back to the same page.
When you click F5 browser resend to server last request. If the last request was a POST it will show a pop up asking user if he wants to resend the information. That's a standard behavior for every browser and you can't change it.
An existing pattern to avoid this problem is /Post/Redirect/Get