Daily Gem: VB / Silverlight / WP7 – Disable Pinch or Scroll in IE9 WebBrowser control

Step 1:  Create a helper class for the WebBrowser

Code Snippet

  1. Imports System.Linq
  2. Imports System.Windows
  3. Imports System.Windows.Controls
  4. Imports System.Windows.Input
  5. Imports Microsoft.Phone.Controls
  6.  
  7.  
  8. Public ClassWebBrowserHelper
  9.     Private _browser As WebBrowser
  10.  
  11.     ”’ <summary>
  12.     ”’ Gets or sets whether to suppress the scrolling of
  13.     ”’ the WebBrowser control;
  14.     ”’ </summary>
  15.     PublicProperty ScrollDisabled() As Boolean
  16.         Get
  17.             Return m_ScrollDisabled
  18.         EndGet
  19.         Set(value As Boolean)
  20.             m_ScrollDisabled = value
  21.         EndSet
  22.     EndProperty
  23.     Private m_ScrollDisabled As Boolean
  24.  
  25.     PublicProperty PinchDisabled() As Boolean
  26.         Get
  27.             Return m_PinchDisabled
  28.         EndGet
  29.         Set(value As Boolean)
  30.             m_PinchDisabled = value
  31.         EndSet
  32.     EndProperty
  33.     Private m_PinchDisabled As Boolean
  34.  
  35.  
  36.     PublicSub New(browser AsWebBrowser)
  37.         _browser = browser
  38.         AddHandler browser.Loaded, NewRoutedEventHandler(AddressOf browser_Loaded)
  39.     EndSub
  40.  
  41.     PrivateSub browser_Loaded(sender As Object, e As RoutedEventArgs)
  42.         Dim border = TryCast(_browser.Descendants(OfBorder)().Last(), Border)
  43.  
  44.         AddHandler border.ManipulationDelta, AddressOf Border_ManipulationDelta
  45.         AddHandler border.ManipulationCompleted, AddressOf Border_ManipulationCompleted
  46.     EndSub
  47.  
  48.     PrivateSub Border_ManipulationCompleted(sender AsObject, e AsManipulationCompletedEventArgs)
  49.         ‘ optionally suppress pinch
  50.         IfPinchDisabled Then
  51.             If e.FinalVelocities.ExpansionVelocity.X <> 0.0 OrElse e.FinalVelocities.ExpansionVelocity.Y <> 0.0 Then
  52.                 e.Handled = True
  53.             EndIf
  54.         EndIf
  55.     EndSub
  56.  
  57.     PrivateSub Border_ManipulationDelta(sender AsObject, e AsManipulationDeltaEventArgs)
  58.         ‘ optionally suppress pinch
  59.         IfPinchDisabled Then
  60.             If e.DeltaManipulation.Scale.X <> 0.0 OrElse e.DeltaManipulation.Scale.Y <> 0.0 Then
  61.                 e.Handled = True
  62.             EndIf
  63.         EndIf
  64.  
  65.         ‘ optionally suppress scrolling
  66.         IfScrollDisabled Then
  67.             If e.DeltaManipulation.Translation.X <> 0.0 OrElse e.DeltaManipulation.Translation.Y <> 0.0 Then
  68.                 e.Handled = True
  69.             EndIf
  70.         EndIf
  71.     EndSub
  72. End Class

Step 2: Add the LinqToVisualTree module, used by the above class to help in locating the browser’s border control

Code Snippet

  1. Imports System.Linq
  2. Imports System.Collections.Generic
  3. Imports System.Windows
  4. Imports System.Windows.Media
  5. Imports System.Runtime.CompilerServices
  6.  
  7. <System.Runtime.CompilerServices.Extension()> _
  8. Module LinqToVisualTree
  9.     ”’ <summary>
  10.     ”’ Adapts a DependencyObject to provide methods required for generate
  11.     ”’ a Linq To Tree API
  12.     ”’ </summary>
  13.     PublicClass VisualTreeAdapter
  14.         ImplementsILinqTree(OfDependencyObject)
  15.         Private _item As DependencyObject
  16.  
  17.         PublicSub New(item AsDependencyObject)
  18.             _item = item
  19.         EndSub
  20.         PublicFunction Children() AsIEnumerable(Of DependencyObject) Implements ILinqTree(OfDependencyObject).Children
  21.             Dim list As New List(OfDependencyObject)
  22.             DimchildrenCount As Integer = VisualTreeHelper.GetChildrenCount(_item)
  23.             For i As Integer = 0 To childrenCount – 1
  24.                 list.Add(VisualTreeHelper.GetChild(_item, i))
  25.             Next
  26.             Return list
  27.         EndFunction
  28.  
  29.         PublicReadOnly Property Parent() AsDependencyObject ImplementsILinqTree(OfDependencyObject).Parent
  30.             Get
  31.                 ReturnVisualTreeHelper.GetParent(_item)
  32.             EndGet
  33.         EndProperty
  34.     EndClass
  35.     ”’ <summary>
  36.     ”’ Defines an interface that must be implemented to generate the LinqToTree methods
  37.     ”’ </summary>
  38.     ”’ <typeparam name="T"></typeparam>
  39.     PublicInterface ILinqTree(Of T)
  40.         Function Children() As IEnumerable(OfT)
  41.  
  42.         ReadOnlyProperty Parent() As T
  43.     EndInterface
  44.  
  45.     ”’ <summary>
  46.     ”’ Returns a collection of descendant elements.
  47.     ”’ </summary>
  48.     <Extension()>
  49.     PublicFunction Descendants(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  50.         Dim adapter As ILinqTree(OfDependencyObject) = NewVisualTreeAdapter(item)
  51.         Dim list As New List(OfDependencyObject)
  52.         ForEach child In adapter.Children()
  53.             list.Add(child)
  54.             Dim ad2 As ILinqTree(OfDependencyObject) = NewVisualTreeAdapter(child)
  55.             ForEach grandChild In child.Descendants()
  56.  
  57.  
  58.                 list.Add(grandChild)
  59.             Next
  60.         Next
  61.         Return list
  62.     EndFunction
  63.  
  64.     ”’ <summary>
  65.     ”’ Returns a collection containing this element and all descendant elements.
  66.     ”’ </summary>
  67.     <Extension()>
  68.     PublicFunction DescendantsAndSelf(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  69.         Dim list As New List(OfDependencyObject)
  70.         list.Add(item)
  71.         ForEach child In item.Descendants()
  72.             list.Add(child)
  73.         Next
  74.         Return list
  75.     EndFunction
  76.  
  77.     ”’ <summary>
  78.     ”’ Returns a collection of ancestor elements.
  79.     ”’ </summary>
  80.     <Extension()>
  81.     PublicFunction Ancestors(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  82.         Dim adapter As ILinqTree(OfDependencyObject) = NewVisualTreeAdapter(item)
  83.         Dim list As New List(OfDependencyObject)
  84.  
  85.         Dim parent = adapter.Parent
  86.         While parent IsNot Nothing
  87.             list.Add(parent)
  88.             adapter = New VisualTreeAdapter(parent)
  89.             parent = adapter.Parent
  90.         EndWhile
  91.         Return list
  92.     EndFunction
  93.  
  94.     ”’ <summary>
  95.     ”’ Returns a collection containing this element and all ancestor elements.
  96.     ”’ </summary>
  97.     <Extension()>
  98.     PublicFunction AncestorsAndSelf(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  99.         Dim list As New List(OfDependencyObject)
  100.         list.Add(item)
  101.  
  102.         ForEach ancestor In item.Ancestors()
  103.             list.Add(ancestor)
  104.         Next
  105.         Return list
  106.     EndFunction
  107.  
  108.     ”’ <summary>
  109.     ”’ Returns a collection of child elements.
  110.     ”’ </summary>
  111.     <Extension()>
  112.     PublicFunction Elements(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  113.         Dim list As New List(OfDependencyObject)
  114.         Dim adapter As ILinqTree(OfDependencyObject) = NewVisualTreeAdapter(item)
  115.         ForEach child In adapter.Children()
  116.             list.Add(child)
  117.         Next
  118.         Return list
  119.     EndFunction
  120.  
  121.     ”’ <summary>
  122.     ”’ Returns a collection of the sibling elements before this node, in document order.    ”’ </summary>
  123.     <Extension()>
  124.     PublicFunction ElementsBeforeSelf(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  125.         Dim list As New List(OfDependencyObject)
  126.         If item.Ancestors().FirstOrDefault() Is NothingThen
  127.             ‘yield Exit Function
  128.             ‘Exit Function
  129.             Return list
  130.         EndIf
  131.         ForEach child In item.Ancestors().First().Elements()
  132.             If child.Equals(item) Then
  133.                 Exit For
  134.             EndIf
  135.             list.Add(child)
  136.         Next
  137.         Return list
  138.     EndFunction
  139.  
  140.     ”’ <summary>
  141.     ”’ Returns a collection of the after elements after this node, in document order.
  142.     ”’ </summary>
  143.     <Extension()>
  144.     PublicFunction ElementsAfterSelf(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  145.         Dim list As New List(OfDependencyObject)
  146.         If item.Ancestors().FirstOrDefault() Is NothingThen
  147.             ‘yield Exit Function
  148.             Return list
  149.             ‘Exit Function
  150.         EndIf
  151.         DimafterSelf As Boolean = False
  152.         ForEach child In item.Ancestors().First().Elements()
  153.             IfafterSelf Then
  154.                 ‘yield Return child
  155.                 list.Add(child)
  156.             EndIf
  157.  
  158.             If child.Equals(item) Then
  159.                 afterSelf = True
  160.             EndIf
  161.         Next
  162.         Return list
  163.     EndFunction
  164.  
  165.     ”’ <summary>
  166.     ”’ Returns a collection containing this element and all child elements.
  167.     ”’ </summary>
  168.     <Extension()>
  169.     PublicFunction ElementsAndSelf(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  170.         Dim list As New List(OfDependencyObject)
  171.         ‘yield Return item
  172.         list.Add(item)
  173.  
  174.         ForEach child In item.Elements()
  175.             ‘yield Return child
  176.             list.Add(child)
  177.         Next
  178.         Return list
  179.     EndFunction
  180.  
  181.     ”’ <summary>
  182.     ”’ Returns a collection of descendant elements which match the given type.
  183.     ”’ </summary>
  184.     <Extension()>
  185.     PublicFunction Descendants(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  186.         Return item.Descendants().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  187.     EndFunction
  188.  
  189.  
  190.  
  191.     ”’ <summary>
  192.     ”’ Returns a collection of the sibling elements before this node, in document order
  193.     ”’ which match the given type.
  194.     ”’ </summary>
  195.     <Extension()>
  196.     PublicFunction ElementsBeforeSelf(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  197.         Return item.ElementsBeforeSelf().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  198.     EndFunction
  199.  
  200.     ”’ <summary>
  201.     ”’ Returns a collection of the after elements after this node, in document order
  202.     ”’ which match the given type.
  203.     ”’ </summary>
  204.     <Extension()>
  205.     PublicFunction ElementsAfterSelf(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  206.         Return item.ElementsAfterSelf().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  207.     EndFunction
  208.  
  209.     ”’ <summary>
  210.     ”’ Returns a collection containing this element and all descendant elements
  211.     ”’ which match the given type.
  212.     ”’ </summary>
  213.     <Extension()>
  214.     PublicFunction DescendantsAndSelf(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  215.         Return item.DescendantsAndSelf().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  216.     EndFunction
  217.  
  218.     ”’ <summary>
  219.     ”’ Returns a collection of ancestor elements which match the given type.
  220.     ”’ </summary>
  221.     <Extension()>
  222.     PublicFunction Ancestors(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  223.         Return item.Ancestors().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  224.     EndFunction
  225.  
  226.     ”’ <summary>
  227.     ”’ Returns a collection containing this element and all ancestor elements
  228.     ”’ which match the given type.
  229.     ”’ </summary>
  230.     <Extension()>
  231.     PublicFunction AncestorsAndSelf(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  232.         Return item.AncestorsAndSelf().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  233.     EndFunction
  234.  
  235.     ”’ <summary>
  236.     ”’ Returns a collection of child elements which match the given type.
  237.     ”’ </summary>
  238.     ”’
  239.     <Extension()>
  240.     PublicFunction Elements(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  241.         Return item.Elements().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  242.     EndFunction
  243.  
  244.     ”’ <summary>
  245.     ”’ Returns a collection containing this element and all child elements.
  246.     ”’ which match the given type.
  247.     ”’ </summary>
  248.     <Extension()>
  249.     PublicFunction ElementsAndSelf(Of T)(item AsDependencyObject) AsIEnumerable(OfDependencyObject)
  250.         Return item.ElementsAndSelf().Where(Function(i) TypeOf i Is T).Cast(OfDependencyObject)()
  251.     EndFunction
  252.  
  253.  
  254.     ”’ <summary>
  255.     ”’ Applies the given function to each of the items in the supplied
  256.     ”’ IEnumerable.
  257.     ”’ </summary>
  258.     <Extension()>
  259.     PrivateFunction DrillDown(items AsIEnumerable(Of DependencyObject), [function] As Func(OfDependencyObject, IEnumerable(OfDependencyObject))) AsIEnumerable(OfDependencyObject)
  260.         Dim list As New List(OfDependencyObject)
  261.         ForEach item In items
  262.             ForEach itemChild In [function](item)
  263.                 ‘yield Return itemChild
  264.                 list.Add(itemChild)
  265.             Next
  266.         Next
  267.         Return list
  268.     EndFunction
  269.  
  270.  
  271.     ”’ <summary>
  272.     ”’ Applies the given function to each of the items in the supplied
  273.     ”’ IEnumerable, which match the given type.
  274.     ”’ </summary>
  275.     <Extension()>
  276.     PublicFunction DrillDown(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject), [function] As Func(OfDependencyObject, IEnumerable(OfDependencyObject))) AsIEnumerable(OfDependencyObject)
  277.         Dim list As New List(OfDependencyObject)
  278.         ForEach item In items
  279.             ForEach itemChild In [function](item)
  280.                 IfTypeOf itemChild Is T Then
  281.                     ‘yield Return DirectCast(itemChild, T)
  282.                     list.Add(DirectCast(itemChild, T))
  283.                 EndIf
  284.             Next
  285.         Next
  286.         Return list
  287.     EndFunction
  288.  
  289.  
  290.     ”’ <summary>
  291.     ”’ Returns a collection of descendant elements.
  292.     ”’ </summary>
  293.     <Extension()>
  294.     PublicFunction Descendants(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  295.  
  296.         Return items.DrillDown(Function(i) i.Descendants())
  297.     EndFunction
  298.  
  299.     ”’ <summary>
  300.     ”’ Returns a collection containing this element and all descendant elements.
  301.     ”’ </summary>
  302.     <Extension()>
  303.     PublicFunction DescendantsAndSelf(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  304.         Return items.DrillDown(Function(i) i.DescendantsAndSelf())
  305.     EndFunction
  306.  
  307.     ”’ <summary>
  308.     ”’ Returns a collection of ancestor elements.
  309.     ”’ </summary>
  310.     <Extension()>
  311.     PublicFunction Ancestors(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  312.         Return items.DrillDown(Function(i) i.Ancestors())
  313.     EndFunction
  314.  
  315.     ”’ <summary>
  316.     ”’ Returns a collection containing this element and all ancestor elements.
  317.     ”’ </summary>
  318.     <Extension()>
  319.     PublicFunction AncestorsAndSelf(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  320.         Return items.DrillDown(Function(i) i.AncestorsAndSelf())
  321.     EndFunction
  322.  
  323.     ”’ <summary>
  324.     ”’ Returns a collection of child elements.
  325.     ”’ </summary>
  326.     <Extension()>
  327.     PublicFunction Elements(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  328.         Return items.DrillDown(Function(i) i.Elements())
  329.     EndFunction
  330.  
  331.     ”’ <summary>
  332.     ”’ Returns a collection containing this element and all child elements.
  333.     ”’ </summary>
  334.     <Extension()>
  335.     PublicFunction ElementsAndSelf(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  336.         Return items.DrillDown(Function(i) i.ElementsAndSelf())
  337.     EndFunction
  338.  
  339.  
  340.     ”’ <summary>
  341.     ”’ Returns a collection of descendant elements which match the given type.
  342.     ”’ </summary>
  343.     <Extension()>
  344.     PublicFunction Descendants(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  345.         Return items.DrillDown(Of T)(Function(i) i.Descendants())
  346.     EndFunction
  347.  
  348.     ”’ <summary>
  349.     ”’ Returns a collection containing this element and all descendant elements.
  350.     ”’ which match the given type.
  351.     ”’ </summary>
  352.     <Extension()>
  353.     PublicFunction DescendantsAndSelf(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  354.         Return items.DrillDown(Of T)(Function(i) i.DescendantsAndSelf())
  355.     EndFunction
  356.  
  357.     ”’ <summary>
  358.     ”’ Returns a collection of ancestor elements which match the given type.
  359.     ”’ </summary>
  360.     <Extension()>
  361.     PublicFunction Ancestors(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  362.         Return items.DrillDown(Of T)(Function(i) i.Ancestors())
  363.     EndFunction
  364.  
  365.     ”’ <summary>
  366.     ”’ Returns a collection containing this element and all ancestor elements.
  367.     ”’ which match the given type.
  368.     ”’ </summary>
  369.     <Extension()>
  370.     PublicFunction AncestorsAndSelf(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  371.         Return items.DrillDown(Of T)(Function(i) i.AncestorsAndSelf())
  372.     EndFunction
  373.  
  374.     ”’ <summary>
  375.     ”’ Returns a collection of child elements which match the given type.
  376.     ”’ </summary>
  377.     <Extension()>
  378.     PublicFunction Elements(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  379.         Return items.DrillDown(Of T)(Function(i) i.Elements())
  380.     EndFunction
  381.  
  382.     ”’ <summary>
  383.     ”’ Returns a collection containing this element and all child elements.
  384.     ”’ which match the given type.
  385.     ”’ </summary>
  386.     <Extension()>
  387.     PublicFunction ElementsAndSelf(Of T AsDependencyObject)(items AsIEnumerable(Of DependencyObject)) As IEnumerable(OfDependencyObject)
  388.         Return items.DrillDown(Of T)(Function(i) i.ElementsAndSelf())
  389.     EndFunction
  390.  
  391.  
  392.     ‘End Namespace
  393. End Module

Now, in your codebehind for XAML pages that use the WebBrowser control where you wish to suppress pinch or scroll, add the following declaration:

  1. Dim WithEvents MBH As WebBrowserHelper

 

Finally, in Public Sub New () of your codebehind of these XAML pages, associate this declared WebBrowserHelper with an actual WebBrowser (in this case named “MyWebBrowser”):

  1. MBH = New WebBrowserHelper(MyWebBrowser)

 

That’s it!

Adapted from C# to VB, and for completeness and accuracy, from:

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

    http://www.scottlogic.co.uk/blog/colin/2011/11/suppressing-zoom-and-scroll-interactions-in-the-windows-phone-7-browser-control/

Leave a comment