Suppressing Zoom and Scroll interactions in the Windows Phone 7 WebBrowser Control

November 17th, 2011 by Colin Eberhardt

This blog post describes a simple helper class that can be used to supress scrolling and pinch zoom of the Windows Phone 7 WebBrowser control.

Developers of Windows Phone 7 application have the full power of IE9 at their disposal in the shape of the WebBrowser control. This control allows you to render both local and remote HTML and JavaScript content within your Silverlight applications. You will find this control used to great effect in RSS readers and Twitter applications such as Rowi, where websites are viewed from within the application rather than by launching the full-blown IE. The WebBrowser control is also used as the host / container for HTML5 based applications, such as Property Finder, the PhoneGap-based application I developed recently.

One problem them people frequently hit against with the WebBrowser control is managing the manipulation events. For example, if you place a WebBrowser control within a Pivot control, how can you pass the horizontal swipe gesture form the WebBrowser to the Pivot?

With HTML5 applications you have a certain amount of control over the browser’s pan and zoom behaviour via the viewport metadata HTML element:

<meta name="viewport" content="user-scalable=no" />

Adding the above meta-tag to a HTML page will prohibit the user from zooming via the pinch gesture. However, it does this in a rather clumsy way – the user can still pinch the page, but when they release, it snaps back to its original scale.

Whilst this might be OK in some contexts, for a HTML5 application where intention is to replicate the feel of a native application as closely as possible, this is just not good enough. Another little browser quirk that has a similar effect is the scroll behaviour. Even if a page fits entirely within the area occupied by the WebBrowser control, they can still scroll the content. Again, it simply snaps back to its original location.

The Solution

I initially thought that there would be no way for me to control the behaviour of the WebBrowser control, it is after-all a very thin .NET wrapper around a native control. However, I stumbled across some StackOveflow answers from quetzalcoatl who had done some digging around in the .NET wrapper and had identified an interesting control called the PanZoomContainer.

If you inspect the visual tree of the WebBrowser control you will find that it is assembled as follows:

\-WebBrowser
  \-Border
    \-Border
      \-PanZoomContainer
        \-Grid
          \-Border (*)
            \-ContentPresenter
              \-TileHost

(visual tree dump generated via the oh-so-useful Linq to VisualTree utility!)

The visual tree is quite simple, composed of a few grids and borders. The significant parts are the TileHost, which is the native IE9 component, and the PanZoomContainer. The TileHost does not handle the mouse manipulation events, these are instead handled by the PanZoomContainer, where they are then translated into gestures (i.e. pinch-zoom) with the result fed back to the TileHost.

What this means is that we can intercept the manipulation events as they bubble up to the PanZoomContainer, cancelling them before they are turned into gestures.

The utility class which I have written handles the events on the Border indicated above. When events are received various conditions are checked to identify pan or scroll interactions, with the events being cancelled accordingly.

The complete class is given below:

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using LinqToVisualTree;
using Microsoft.Phone.Controls;
 
/// <summary>
/// Suppresses pinch zoom and optionally scrolling of the WebBrowser control
/// </summary>
public class WebBrowserHelper
{
  private WebBrowser _browser;
 
  /// <summary>
  /// Gets or sets whether to suppress the scrolling of
  /// the WebBrowser control;
  /// </summary>
  public bool ScrollDisabled { get; set; }
 
  public WebBrowserHelper(WebBrowser browser)
  {
    _browser = browser;
    browser.Loaded += new RoutedEventHandler(browser_Loaded);
  }
 
  private void browser_Loaded(object sender, RoutedEventArgs e)
  {
    var border = _browser.Descendants<Border>().Last() as Border;
 
    border.ManipulationDelta += Border_ManipulationDelta;
    border.ManipulationCompleted += Border_ManipulationCompleted;
  }
 
  private void Border_ManipulationCompleted(object sender,
                                            ManipulationCompletedEventArgs e)
  {
    // suppress zoom
    if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
        e.FinalVelocities.ExpansionVelocity.Y != 0.0)
      e.Handled = true;
  }
 
  private void Border_ManipulationDelta(object sender,
                                        ManipulationDeltaEventArgs e)
  {
    // suppress zoom
    if (e.DeltaManipulation.Scale.X != 0.0 ||
        e.DeltaManipulation.Scale.Y != 0.0)
      e.Handled = true;
 
    // optionally suppress scrolling
    if (ScrollDisabled)
    {
      if (e.DeltaManipulation.Translation.X != 0.0 ||
        e.DeltaManipulation.Translation.Y != 0.0)
        e.Handled = true;
    }
  }
}

Within Property Finder, my HTML5 application, as the user navigates from one page to the next, the JavaScript code notifies the Silverlight container whether the current page should have scrolling disabled, setting the ScrollDisabled property of the above helper class accordingly.

I hope other people find this simple utility class useful. To use it, just cut and paste the code given above. Note, it uses Linq to VisualTree to navigate the WebBrowser visual tree, so you will need to go and grab that also.

Regards, Colin E.

Tags: , , ,

30 Responses to “Suppressing Zoom and Scroll interactions in the Windows Phone 7 WebBrowser Control”

  1. Apu says:

    Hi,
    I have used this and its working fine for me. But now next question is, I want to disable the selection color on web browser(setting the color to Transparent), do you have any idea how can I achieve that?

    Thanks
    /
    Apu

  2. Prakash says:

    That is an amazing perception. I have a webBrowser which has to scroll vertically and not horizontally so I can use your solution with a little modification.

  3. [...] just want to turn off scrolling/zooming of the webpage. Colin Eberhardt did the initial research (blog post here) and discovered how the WebBrowser control’s view stack is defined, and discovered how to prevent [...]

  4. [...] the way I have solved problems such as back-button support, tombstoning and suppressing browser pan and zoom. var addthisButtonFacebook = document.getElementById('addthisButtonFacebook'); var [...]

  5. yuhb says:

    If you flick up the webbrowser control instead of drag, it still can scroll. Any thought?

  6. Gnanaselvam says:

    We are facing an issue in locking pinch zoom and scroll lock in
    browser web page. We have created an application using phonegap.In that web page, we
    want to lock the pinch zoom and scroll lock(Lock for Web View) in Windows Phone 7.5 mango

  7. Alius says:

    Can you show an example how to use this class? I’m just HTML5 developer, and all C# things is new to me. But I need this fix for PhoneGap…

    Thanks in advance

  8. Angel says:

    Hi Colin E.,

    This solution works with a PhoneGap project like your Property Finder? And works in the WP7 Emulator? Because I start a Hello World PhoneGap project, added the WebBrowserHelper.cs and VisualTreeAdapter.cs classes but nothing changes… the zoom and scroll effects persist.
    Where I find a complete example or how did you configured your files and MainPage.xaml MainPage.xaml.cs?

    Thank you for your patience…

  9. Gnanaselvam says:

    I am HTML5 mobile games and apps developer. i use the above code but i gave some error
    at the line in var border = _browser.Descendants().Last() as Border; Microsoft.Phone.Controls.WebBrowser does not contain a definition for descendants and the best extension methos overload and Instance argument cannot convert from Microsoft.Phone.Controls.WebBrowser toSystem.Collections.Generic.IEnumerable’
    I added the reference in System.Xml.Linq. how to solve the error or how to disable the page scrolling and zooming controls in web browser in WP7

  10. Apu says:

    Hi,
    I am trying with your example but ” _browser.Descendants().Last() as Border;” is showing error. Its showing “‘Microsoft.Phone.Controls.WebBrowser’ does not contain a definition for ‘Descendants’ ”

    I am using Windows Phone SDK 7.1. Do you have any idea why its not working?

    Thanks
    /
    Apu

  11. Adam says:

    I tried looking through your code for Property Finder to see how you’re implementing WebBrowserHelper, but I can’t find any mention of it. How are you implementing it? I got the code from this page: http://www.scottlogic.co.uk/blog/colin/2011/11/property-finder-the-first-html5-based-windows-phone-7-application/

  12. Rafael says:

    Hi,

    I am an Android programmer and I’m venturing in C# world to make webapps to WP7 and I get confused with your solution for suppressing zoom and scrool interactions.
    The C# is many different from Java and I will be honest, I do not understand how to implement your solution…
    For example, I started a “Hello World” PhoneGap project and I added WebBrowserHelper.cs class and VisualTreeAdapter.cs class but I don’t understand where I call de utility class WebBrowserHelper in this project.
    Is it asking too much if you could demonstrate it such as Property Finder, the PhoneGap-based application that you developed recently?

  13. slyi says:

    Since WP7 IE 9 does not support touchmove events http://blogs.msdn.com/b/iemobile/archive/2011/02/14/ie9-coming-to-windows-phone-in-2011.aspx
    Could you intercept these pinch/pan calls and call them in JS with invokescript to provide a touch events polyfill for MS Surface like demos?

    http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
    http://www.midemos.com/demos/iphone/touch/

  14. Srinath says:

    Oh thanks. It works.

  15. Hm, is it working only in Mango?

    My project is still targeting WP OS 7.0, the Border’s events aren’t firing.

    Any glues?

    • Yes, this will only work on Mango – the WebBrowser control in WP7.0 was quite different, it handles manipulation events internally – in the native layer, so there is no opportunity to intercept.

  16. Hey, thanks for this!

    I’ve been annoyed by pinching in WebBrowser but haven’t found a solution to disable it.

Leave a Reply