Windows Phone 8 Back button to go back in WebBrowser - c#

I made a WebBrowser and it works except the back button after pressing the back button the app closes and does not go back one in history. How can I solve the problem? I found solutions in the internet but they don't seem to work.
public MainPage()
{
this.InitializeComponent();
this.webBrowser.Navigate(new Uri("http://www.google.com", UriKind.Absolute));
this.webBrowser.LoadCompleted += webBrowser_LoadCompleted;
this.webBrowser.NavigationFailed += webBrowser_NavigationFailed;
this.webBrowser.IsScriptEnabled = true;
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
webBrowser.InvokeScript("eval", "history.go(-1)" );
}
P. S.:that is not the whole script but i think the rest is unneccesary if not tell me :)
P. P. S.:I'm new to Windows Phone programing.

Web browser is just a control inside the page and pressing the device back button navigates back to the previous page or exits the app if it has only one page. So, you would need to stop page navigation on back key press something like this.
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
e.Cancel=true;
}
This prevents a backnavigation
Now rest is to go to the previous page which can be done by
webBrowser.InvokeScript("eval", "history.go(-1)" );
so the event becomes
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
e.Cancel=true;
webBrowser.InvokeScript("eval", "history.go(-1)" );
}

Try to do:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
WB1.InvokeScript("eval", "history.go(-1)");
e.Cancel = true;
}
When you override OnBackKeyPress, and you don't perform e.Cancel = true; it will do your code, but will also do what normal BackButton does - NavigateBack, Exit App and so on. But you must remember to leave the User an ability to exit your App or Navigate Back, so it will be more suitable to check some conditions (e.g. your webbrowser history is not null) and then do e.Canel, otherwise Exit the App.

To exit the app when you are in the root (so you can approve the cerfitication requirements), and also go back in navigation until you are in the root, try with this
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (MiniBrowser.CanGoBack){
e.Cancel = true;
MiniBrowser.InvokeScript("eval", "history.go(-1)");
}
}

Related

Make app exit in OnBackButtonPressed method for xamarin forms

I have an application in which user logins. Now I want that user can't go back to the menu after he presses the logout button.
This is my logout method
public async void OnLogoutButtonClicked(object sender, EventArgs e)
{
App.AuthenticationClient.UserTokenCache.Clear(Constants.ApplicationID);
await Navigation.PushAsync(new LoginPage());
}
So after logout button is clicked it pushes the user to login page.
I'm able to disable the back button using this in login page
protected override bool OnBackButtonPressed()
{
return false;
}
But it makes my app feel not responsive, instead, I want that when the back button is pressed my app should close the application.
I tried this
protected override bool OnBackButtonPressed()
{
return exit();
//
// exit()
}
but it returns boolean, what should I do to make it work?
When the user logs out, you generally don't want to push a new page on the existing navigation stack. The current navigation stack is not longer applicable, so should be discarded, much like how you clear the UserTokenCache.
So your logout method should be more like:
public async void OnLogoutButtonClicked(object sender, EventArgs e)
{
App.AuthenticationClient.UserTokenCache.Clear(Constants.ApplicationID);
Application.Current.MainPage = new LoginPage();
}
Basically, create the new LoginPage and set up a new MainPage, just as though the app were starting and first presenting the user with a LoginPage.
If you do that, then the back button can't get back to the menu, because that whole navigation stack is gone.

How to override back button for a page outside of it?

I know how to override back button inside a page:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
//Do your work here
base.OnBackKeyPress(e);
}
But the problem: I use Inneractive ad service. when I call InneractiveAd.DisplayAd() it shows a new page of its own which doesn't support back button. when it navigate to this page its uri is like this:
/Inneractive.Ad;component/InneractiveFullScreenPage.xaml
The question: is it possible to override back button of that page to navigate back when user presses back?
In HandleBackKeyPress you usually intercept BackKeyPress event, so you would set e.Cancel = true to prevent standard BackKey navigation. To simulate standard navigation you would do something like:
void HookUpBackKeyPress(PhoneApplicationPage page)
{
page.BackKeyPress += HandleBackKeyPress;
}
void HandleBackKeyPress(object sender, CancelEventArgs e)
{
page.NavigationService.GoBack();
}
The problem is to get the reference to the navigated page. The following code will work only after you completely Navigated to the new Page and it might not work when immediately after NavigationService.Navigate(..)
var frame = (PhoneApplicationFrame)Application.Current.RootVisual;
page = (PhoneApplicationPage)frame.Content;

How to know if navigating from other page or from a Task?

In my app, I have a page where I navigate from the MainPage.xaml. A CameraCaptureTask is launched from that page.
I would like to know, on page loading, how can I know if I have navigated from MainPage.xaml, or it came back from CameraCaptureTask.
Using the NavigationService.BackStack.FirstOrDefault() doesn't help, because, as expected, it returns the MainPage.xaml.
I'd like something like:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (/*Navigated-from-MainPage-but-not-from-CameraCaptureTask*/)
{
// Do Something
}
}
You can accomplish this in one of two ways. The first is to listen to the Completed event of the CameraCaptureTask
CameraCaptureTask task = new CameraCaptureTask();
task.Completed += new EventHandler<PhotoResult>(OnCaptureTaskCompleted);
task.Show();
...
void OnCaptureTaskCompleted(object sender, PhotoResult e)
{
// Navigated back or took a picture
}
The second way is to check the NavigationMode of the NavigationEventArgs. If the value is Back, then you know you navigated back from the CameraCaptureTask (assuming that this page does not navigate to any other pages)
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
// came back from CameraCaptureTask
}
}

Silverlight callback mystery behavior

I am writting this method to track if changes occured on a page so the user can trigger a reload of a dependent system. So this as you can see triggers when the user is trying to navigate away from the page. If the e.Cancel is not there the behavior seems fine the async web-service call happen as expected but I am not sure what is really happening in the back.
The reload button click method triggers a chain of event that usually update the display but since the user has navigated away from the page the components are no longer visible. Can this cause problems to the application? Should I be forcing the user to remain on the same page just to prevent possible callback problems?
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
if (hasDataBeenModified)
{
if (System.Windows.Browser.HtmlPage.Window.Confirm("You have not reloaded the policies\nDo you want to do it now?"))
{
//e.Cancel = true;
ReloadButton_Click(null, null);
}
}
}
Instead of using OnNavigatingFrom, use OnBackKeyPress
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (hasDataBeenModified)
{
if (System.Windows.Browser.HtmlPage.Window.Confirm("You have not reloaded the policies\nDo you want to do it now?"))
{
e.Cancel = true;
ReloadButton_Click(null, null);
}
}
}

Adding back and forward button for WebBrowser control

I have a WebBrowser element in a page, to which I would like to add a back and forward buttons, and have those buttons disabled when there's nothing to go back to and nothing to go forward to.
In Cocoa, the UIWebView has methods to easily check that: canGoBack and canGoForward, and you have goBack and goForward methods available (along with reload etc..)
Android has the exact same method names for achieving the same.
I see those methods are available in .Net 4 and 3.5 SP1.
I've found some references about using javascript commands in Silverlight but I find this very cumbersome, plus there's no way to detect if there's anything in the history (unless of course I manage this myself)
Surely, there's something a tad more advanced in Windows Phone ..
Here is how I ended up doing it.
This assumes you have set a backButton and forwardButton; the status of these buttons will be updated accordingly depending on where you are in the navigation stack.
webView is the WebBrowser object
List<Uri> HistoryStack;
int HistoryStack_Index;
bool fromHistory;
// Constructor
public HelpView()
{
InitializeComponent();
HistoryStack = new List<Uri>();
HistoryStack_Index = 0;
fromHistory = false;
webView.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(WebView_Navigated);
UpdateNavButtons();
}
private void backButton_Click(object sender, RoutedEventArgs e)
{
if (HistoryStack_Index > 1)
{
HistoryStack_Index--;
fromHistory = true;
webView.Navigate(HistoryStack[HistoryStack_Index-1]);
updateNavButtons();
}
}
private void forwardButton_Click(object sender, RoutedEventArgs e)
{
if (HistoryStack_Index < HistoryStack.Count)
{
HistoryStack_Index++;
fromHistory = true;
webView.Navigate(HistoryStack[HistoryStack_Index-1]);
UpdateNavButtons();
}
}
private void UpdateNavButtons()
{
this.backButton.IsEnabled = HistoryStack_Index > 1;
this.forwardButton.IsEnabled = HistoryStack_Index < HistoryStack.Count;
}
private void WebView_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (!fromHistory)
{
if (HistoryStack_Index < HistoryStack.Count)
{
HistoryStack.RemoveRange(HistoryStack_Index, HistoryStack.Count - HistoryStack_Index);
}
HistoryStack.Add(e.Uri);
HistoryStack_Index++;
UpdateNavButtons();
}
fromHistory = false;
}
I have a back button added to the applicationbar of a page in one of my apps which contains a webbrowser. I wanted the back button in the app bar to take the web page navigation backward, and wanted the hardware back button to go to the previous xaml page. This way, the user doesn't have to use the hardware back button to navigate backward through all the visited web pages in the webbrowser in order to go back to the prior xaml page. Here is how I did it, and you could easily set up a forward stack and when the user clicks the back (appbar) button, the page pops from that stack and is pushed to the forward stack.
private void NavigateWeb()
{
if (!loaded)
{
NavigationStack.Clear();
try
{
Web.Source = new Uri("http://m.weightwatchers.com/");
loaded = true;
}
catch (Exception ex)
{
MessageBox.Show("Unable to navigate to page.\n" + ex.Message,
"Error", MessageBoxButton.OK);
}
}
}
void Web_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
NavigationStack.Push(e.Uri);
}
void btnBack_Click(object sender, EventArgs e)
{
if (NavigationStack.Count > 2)
{
// get rid of the topmost item...
NavigationStack.Pop();
// now navigate to the next topmost item
// note that this is another Pop - as when the navigate occurs a Push() will happen
Web.Navigate(NavigationStack.Pop());
}
}
The reason I check for NavigationStack.Count > 2 is that the particular webpage that I'm showing in the webbrowser always starts with a "click here to continue" link on the first page, and there is no reason to go back to there. That's the downfall of showing other people's sites in your webbrowser - you don't have control over what is shown.
In regards to the javascript solution it is doing something like this:
private void backButton_Click(object sender, RoutedEventArgs e)
{
try
{
webView.InvokeScript("eval", "history.go(-1);");
}
catch
{
// Eat error
}
}
private void forwardButton_Click(object sender, RoutedEventArgs e)
{
try
{
webView.InvokeScript("eval", "history.go(1);");
}
catch
{
// Eat error
}
}
with having the IsScriptingEnabled set to true for the WebBrowser element.
However, this always generates an exception with error 80020006. I read various posts about how the DOCTYPE could have been the culprit, the system caching or IsScriptEnabled being set after the content was loaded... It just never worked...

Categories

Resources