How to embed a WebBrowser control inside a Pivot Item in Windows Phone

I had an application that required a WebBrowser control within one of the PivotItem instances in a Pivot control.  There is nothing stopping you from having the Content property of the PivotItem be a WebBrowser control instance except that when you run the application, the WebBrowser interferes with the touch / swiping controls of the Pivot control. 

As you start swiping left or right, after you land on the PivotItem with the browser control, the browser instance will essentially “take“ the swipes and not allow its parent (the PivotItem and the Pivot) to respond to them. This means that the user won't be able to swipe left/right if their swipe was in the pivot body. If they swipe within the header of the pivot control, then that'll work fine. This is because the web browser control instance sees those swipes and thinks you’re trying to pan the content within the browser to the left or right and doesn't know anything about it's parent container.  To fix this experience, you’ll need to tap into the element tree of the WebBrowser and watch for swipes yourself and then manually change the SelectedIndex of the Pivot control accordingly.  It sounds tricky but it isn’t too bad. And I’m also giving you a sample project which you can reference (it's attached to this blog post).

So to make this work, here’s the 3 things you need to do:

 

1) After the browser’s Loaded event fires, get a handle to last Border element within the browser control. LinqToVisualTree will do the grunt work for you, so just reference that in your project.

 var border = _browser.Descendants<Border>().Last() as Border;

 

2) After you get a handle to the border element, subscribe to its ManipulationDelta event. This event tells you when and how the user might have touched the element.

 

3) Whenever the ManipulationDelta event fires, you’ll need to look at the DeltaManipulation.Translation event argument and examine the X and Y values to see which direction the user might have swiped within the control. A positive X value means the user moved right, negative X value means they moved left. A positive Y value means they moved upwards, a negative Y value means they moved downwards. But you need to be careful here. Just because you see a change in the X value doesn’t mean the user swiped left or right. They very well could have been swiping up/down to pan vertically in the web browser and but they didn’t move their finger in a perfecty straight vertical line. No one will ever do that. So you need to be a little smart here with the logic and try to figure out if they absolutely are trying to swipe left or right to move to another pivot. The way I did it is to compare the X to the Y values and then add in some buffer by checking to see if the X delta movement is at least 5 times greater than the Y delta. If it is, then its almost certain the user is trying to move pivots. If it’s less than that, well then perhaps they were actually trying to pan vertically but they were holding the phone in such a way that their swipes were diagonal across the screen. You’ll need to determine what the right threshold is for your app but hopefully should be easy to do with this sample:

  var x = e.DeltaManipulation.Translation.X;
 var y = e.DeltaManipulation.Translation.Y; 
 // Make the deltas positive numbers for calculating the threshold
 var xAb = Math.Abs(x);
 var yAb = Math.Abs(y);
 
 // Ensure that the horizontal scroll is greater than the vertical scroll amount. 
 // In case the user swipes diagonally, ensure that the horizontal scroll is at least 5x bigger than the vertical
 // scroll to eliminate any accidental pivot changes.
 if (xAb > (5 * yAb))
 {
 if (x < y)
 {
 // Go right
 e.Handled = true;
 _pivot.SelectedIndex = Math.Min(_pivot.Items.Count - 1, _pivot.SelectedIndex + 1);
 }
 else if (x > y)
 {
 // Go left
 e.Handled = true;
 _pivot.SelectedIndex = Math.Max(0, _pivot.SelectedIndex - 1);
 }
 }
 

One thing to note is that this only really will work for you if the content you are displaying in the WebBrowser control doesn’t need to pan horizontally.  If you need to support that, well then you have a big design issue on your page that you need to address regarding multiple controls needing to support swiping horizontally.  And if you’re going to be reusing this logic across multiple Pivot control instances, see the sample project where I’ve taken the above and wrapped it into a helper class making reuse a little easier.

Good luck!

PivotWithWebBrowserSample.zip