This post is in response to a question someone asked in the Microsoft App Hub forum and because I was plain curious. That thread is here: http://forums.create.msdn.com/forums/t/72708.aspx
So, in Windows Phone Silverlight programming, we have access to a WebBrowser control. This is essentially a stripped-down version of the IE browser in the OS and can be slapped onto any XAML page. The WebBrowser control can then be asked to load any webpage (or local HTML), including ones with JavaScript interaction; it does not seem to handle HTTPS certificates too well though.
Now, what if you use the WebBrowser control within your XAML page to display web content & the user clicks on a link on a webpage? Yes, you guessed it right; the WebBrowser control loads the destination page. What if the user wants to come back to the first webpage? Hmmm .. this is tricky. Unlike the full-blown IE, the WebBrowser control does not maintain a backstack, as far as I can tell. Also, if you try overriding the hardware WP7 Back button, you might be walking on the edges of app certification requirements; the hardware button is supposed to take the user back out of the XAML page and onto the last history in the app page backstack; not to the last webpage loaded by the WebBrowser control!
So, it seems like a custom solution is called for when needing to support navigation in a WebBrowser control. Following is what I whipped up rather quickly; so BIG disclaimer – this custom browser backstack does *not* work for anything but the simplest of web pages. No postbacks or Jscript or cookies or URL params are supported. You may off course take the concept and extend this to your needs.
Here is how the quick demo app looks like. We take URL inputs from the user & display the page within a WebBrowser control embedded in the page. The user is free to click on any links on web pages to navigate elsewhere, with the destinations URLs loaded in the same place. Also, we throw in two Software navigation buttons in the App Bar, for supporting Forward/Back navigation of the content displayed.
Now, here’s the little requisite code. Since we are creating a custom backstack, some data constructs are needed; at a minimum a List/Dictionary data structure to remember the URLs for forward & backward navigation. Again, this was my way of doing things; feel free to trail braze with your own logic.
List<string> URLStack = new List<string>();
int position = -1;
bool navigationButtonClicked = false;
The WebBrowser does raise events, which give us the opportunity to capture the URL of the page it is loading. We do, however, need to differentiate between when the user simply clicked on a link versus when he hit the navigation buttons.
private void MyWebBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (this.MyWebBrowser.Source != null && !this.navigationButtonClicked)
{
if (position == 0)
{
string firstURL = this.URLStack[0];
this.URLStack.Clear();
this.URLStack.Add(firstURL);
}
this.URLStack.Add(this.MyWebBrowser.Source.ToString());
position++;
}
this.navigationButtonClicked = false;
}
And the Back & Front navigation buttons have the following code behind their event handlers. You may update the URL Textbox accordingly.
private void Back_Click(object sender, EventArgs e)
{
this.navigationButtonClicked = true;
this.MyWebBrowser.Navigate(new Uri(this.URLStack[position - 1].ToString()));
position--;
}
private void Forward_Click(object sender, EventArgs e)
{
if (this.URLStack.Count > position + 1)
{
this.navigationButtonClicked = true;
this.MyWebBrowser.Navigate(new Uri(this.URLStack[position + 1].ToString()));
position++;
}
}
That’s it; a simple browser navigation example with custom URL stack. Hope this was somewhat useful.
Adios!