Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly handle web browser control back navigation

I am attempting to perform proper back stack navigation in a web browser control that I have placed in my WP7 application. The web browser is in a custom control in which I implement navigation methods, and then I place this control in a page in my application. Navigation seems to work properly, except for the backstack. Sometimes it goes back to the previous page, and other times (when its not supposed to) it closes the application. Here is my implementation so far:

WebBrowser.cs (user control)

    //The navigation urls of the browser.
    private readonly Stack<Uri> _NavigatingUrls = new Stack<Uri>();

    //The history for the browser
    private readonly ObservableCollection<string> _History =
       new ObservableCollection<string>();

    //Flag to check if the browser is navigating back.
    bool _IsNavigatingBackward = false;


    /// <summary>
    /// Gets the History property for the browser.
    /// </summary>
    public ObservableCollection<string> History
    {
        get { return _History; }
    }

    /// <summary>
    /// CanNavigateBack Dependency Property
    /// </summary>
    public static readonly DependencyProperty CanNavigateBackProperty =
        DependencyProperty.Register("CanNavigateBack", typeof(bool),
        typeof(FullWebBrowser), new PropertyMetadata((bool)false));

    /// <summary>
    /// Gets or sets the CanNavigateBack property. This dependency property
    /// indicates whether the browser can go back.
    /// </summary>
    public bool CanNavigateBack
    {
        get { return (bool)GetValue(CanNavigateBackProperty); }
        set { SetValue(CanNavigateBackProperty, value); }
    }


    void TheWebBrowser_Navigating(object sender,
        Microsoft.Phone.Controls.NavigatingEventArgs e)
    {
        //show the progress bar while navigating
    }

    void TheWebBrowser_Navigated(object sender,
        System.Windows.Navigation.NavigationEventArgs e)
    {
        //If we are Navigating Backward and we Can Navigate back,
        //remove the last uri from the stack.
        if (_IsNavigatingBackward == true && CanNavigateBack)
            _NavigatingUrls.Pop();

        //Else we are navigating forward so we need to add the uri
        //to the stack.
        else
        {
            _NavigatingUrls.Push(e.Uri);

            //If we do not have the navigated uri in our history
            //we add it.
            if (!_History.Contains(e.Uri.ToString()))
                _History.Add(e.Uri.ToString());
        }

        //If there is one address left you can't go back.
        if (_NavigatingUrls.Count > 1)
            CanNavigateBack = true;
        else
            CanNavigateBack = false;

        //Finally we hide the progress bar.
        ShowProgress = false;
    }

    /// <summary>
    /// Used to navigate back.
    /// </summary>
    public void NavigateBack()
    {
        _IsNavigatingBackward = true;
        TheWebBrowser.InvokeScript("eval", "history.go(-1)");
    }

BrowserPage.xaml.cs

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
    {
        if (TheBrowser.CanNavigateBack)
        {
            e.Cancel = true;
            TheBrowser.NavigateBack();
        }
        else
            base.OnBackKeyPress(e);
    }

Note: Javascript is enabled in my webbrowser and all other navigation works correctly. My issue is that sometimes the web browswer navigates back correctly, and other times it does not work and closes all together. Is there an issue with my impelementation? What might I do to solve this?

like image 412
Matthew Avatar asked Mar 23 '26 04:03

Matthew


1 Answers

Is it just me or are you creating an infinite circular reference when you call base.OnBackKeyPress(e) - so when the backwards navigation is not available, it will try to re-send the event back to itself, in fact, you don't need to do this, by not doing a e.Cancel = true; you will automatically allow the OnBackKeyPress event to continue without any issue, so remove the else part entirely and see what happens. Since you're getting the error when back nav isnt available, it kind of makes sense that the circular reference is being initiated only then.

Keep in mind, I'm a VB.NET programmer, so unless there is something very different about C# that I haven't picked up on, we might be onto a solution.

The fact that you are doing an e.cancel=true; suggests that if you didn't do it, the event will continue, therefore, re-initiating the event isn't necessary (since you're not canceling it), and is probably creating a circular reference. Try removing it and let us know what happens. That is, you'd need to remove the following lines:

 } 
        else 
            base.OnBackKeyPress(e); 
like image 100
Erx_VB.NExT.Coder Avatar answered Mar 25 '26 18:03

Erx_VB.NExT.Coder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!