Thursday 4 November 2010

Windows Phone 7, How to use the Map control on a Pivot or Panorama


Place a Bing map control on a Pivot or Panorama in Windows Phone 7 and you'll notice that every time you try to manipulate the map with a swipe to left or right the Pivot/Panorma will move as well. In fact performing a swipe on the Map control as soon as the application starts without even ever touching the Pivot/Panorama results in a 'NullRefrenceException' with the following trace stack:
"at Microsoft.Phone.Gestures.GestureHelper.ReleaseMouseCaptureAtGestureOrigin()\r\n at Microsoft.Phone.Gestures.GestureHelper.NotifyMove(InputDeltaArgs args)\r\n at Microsoft.Phone.Gestures.ManipulationGestureHelper.Target_ManipulationDelta(Object sender, ManipulationDeltaEventArgs e)\r\n at System.Windows.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)\r\n at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, String eventName)\r\n"
(Interestingly enough the Microsoft.Phone.Gestures namespace appears to be completely undocumented. It can be added in your using section but will be unresolvable until compilation.)

The problem however seems to stem from the fact that both controls are triggered by the same Gesture motion. Some therefore say that utilizing the Map control on a Pivot\ Panorama is either not a good idea or not even possible.
That apporoach however strikes me as incorrect because just by setting the Map controls IsHitTestVisible="False" the problem no longer occurs and you can use the map in read only mode.

But what if you really want to use the map control and just not have the Pivot/Panorama respond to gestures clearly aimed at the map?
Well instead of disabling the IsHitTestVisible property of the Map use the Maps MouseLeftButtonDown event to set the Panorama's to false
private
void MapOne_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

this.PanOne.IsHitTestVisible = false;

}

Just don't forget to use the ApplicationPage's MouseLeftButtonUp event to restore it otherwise the application will become nonresponsive.
private
void PhoneApplicationPage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)

{

this.PanOne.IsHitTestVisible = true;

}
(use the application page one beceause the Maps MouseLeftButtonUp event doesn't fire if your swipe ended outside the control)
There is a drawback to this. At least in my emulator the map control seems a bit more unresponsive.
Could be an emulator thing, could be there is a better even to hook up to. I'll work on that to see if I can get a better solution.

-Leon