Technology

Writing a Bing Maps location aware application for Windows Phone 7 Series

Anthony Marshall
Anthony Marshall
16 Mar 2010
blog post featured image
<p><a href="http://earthware-website.azurewebsites.net/Content/images/wp-images/2010/03/image4.png"><img style="border-right-width: 0px; margin: 0px 0px 20px 20px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="right" src="http://earthware-website.azurewebsites.net/Content/images/wp-images/2010/03/image4-thumb.png" width="204" height="394" /></a>If you have been keeping up with the news from Mix2010 and <a href="http://live.visitmix.com/MIX10/Sessions/KEY01" target="_blank">yesterdays’ keynote</a> you will know a number of exciting things have been released for windows phone 7 series:</p> <ul> <li><font face="Arial">completely free <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2338b5d1-79d8-46af-b828-380b0f854203&amp;displaylang=en" target="_blank">developer tools</a></font> </li> <li><font face="Arial">the windows 7 phone series beta sdk</font> </li> <li><font face="Arial">lots of details about using silverlight and xna to develop phone applications</font> </li> </ul> <p>So what does that mean for Bing Map, will there be a new silverlight control for mobile? There may well be an update to better support mobile development but you can start right now using the current Bing Maps silverlight control and it works! To show you how here is a quick tutorial creating your first location aware Bing Maps phone application.</p> <h4>Prerequisites</h4> <ul> <li><font face="Arial">The <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2338b5d1-79d8-46af-b828-380b0f854203&amp;displaylang=en" target="_blank">Windows Phone 7 Series SDK</a></font> </li> <li><font face="Arial">The <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=beb29d27-6f0c-494f-b028-1e0e3187e830" target="_blank">Bing Maps Silverlight control</a></font> </li> </ul> <h4>Getting Started</h4> <p>Start by opening Visual Studio 2010 (or express as offered free in the sdk) and create a new project, selecting the “Windows Phone Application” project template.</p> <p><a href="http://earthware-website.azurewebsites.net/Content/images/wp-images/2010/03/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://earthware-website.azurewebsites.net/Content/images/wp-images/2010/03/image-thumb1.png" width="466" height="149" /></a></p> <p>Now add references to the Bing Maps silverlight control (usually found in <em>C:\Program Files\Bing Maps Silverlight Control\V1\Libraries</em>). You may find you need to also add a reference to System.Windows.Browser to get it to compile correctly (<em>from c:\Program Files\Microsoft Silverlight\4.0.50303.0\</em>).</p> <p>Finally for the setup, add a reference to <em>System.Device.Location</em>.</p> <h3>Creating a Basic User Interface</h3> <p>Now we have the project created lets create a simple user interface in XAML that has a Bing Map Control, a status bar and a start button. First add the Bing Maps namespace to you MainPage.xaml file: <br /> <br /><font color="#808080">xmlns:m=&quot;clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl&quot;</font></p> <p>Then add the following block of XAML in the grid named “ContentGrid” which should already be in MainPage.xaml:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0d50d774-4aea-4bb7-a614-31d1146e30a4" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #0000ff">&lt;</span><span style="color: #a31515">m</span><span style="color: #0000ff">:</span><span style="color: #a31515">Map</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;mapMain&quot;</span><span style="color: #ff0000"> NavigationVisibility</span><span style="color: #0000ff">=&quot;Collapsed&quot;</span><span style="color: #ff0000"> Mode</span><span style="color: #0000ff">=&quot;AerialWithLabels&quot;</span><span style="color: #ff0000"> CredentialsProvider</span><span style="color: #0000ff">=&quot;ADD_YOUR_BINGMAPS_KEY_HERE&quot;&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">m</span><span style="color: #0000ff">:</span><span style="color: #a31515">Map</span><span style="color: #0000ff">&gt;</span> </li> <li><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Border</span><span style="color: #ff0000"> Background</span><span style="color: #0000ff">=&quot;Black&quot;</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">=&quot;40&quot;</span><span style="color: #ff0000"> Opacity</span><span style="color: #0000ff">=&quot;0.7&quot;</span><span style="color: #ff0000"> VerticalAlignment</span><span style="color: #0000ff">=&quot;Top&quot;&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;tbStatus&quot;</span><span style="color: #ff0000"> Text</span><span style="color: #0000ff">=&quot;Click below to start&quot;</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">=&quot;5 5 0 0&quot; /&gt;</span> </li> <li>&#160;&#160; <span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Border</span><span style="color: #0000ff">&gt;</span><span style="color: #a31515"></span> </li> </ol> </div> </div> </div> <p>Now change the name of the application and the title to be whatever you want. Hit F5 and you should get the emulator load up with you application showing a Bing Map!&quot;</p> <h3>Making it actually do something</h3> <p>For the next part of the tutorial we are going to make the application actually do something with the map by making it location aware, that is to say use the devices location to change the map in some way.</p> <p>First add the following to your XAML just under the map control, to add a button:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6f39d174-123c-46dc-9dee-2c5dfd5aa13b" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; max-height: 200px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Button</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;btnStart&quot;</span> <span style="color: #ff0000">Click</span><span style="color: #0000ff">=&quot;btnStart_Click&quot;</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">=&quot;260&quot;</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">=&quot;40&quot;&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Button.Content</span><span style="color: #0000ff">&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">StackPanel</span><span style="color: #ff0000"> Orientation</span><span style="color: #0000ff">=&quot;Horizontal&quot;&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Path</span><span style="color: #ff0000"> Fill</span><span style="color: #0000ff">=&quot;White&quot;</span><span style="color: #ff0000"> Data</span><span style="color: #0000ff">=&quot;F1 M 2.339,6.489 C 1.193,5.343 1.193,3.485 2.339,2.339 C 3.485,1.192 5.344,1.193 6.489,2.339 C 7.635,3.485 7.635,5.343 6.489,6.489 C 5.344,7.636 3.485,7.636 2.339,6.489 Z M 11.711,10.209 L 8.185,6.684 C 9.207,4.986 9.000,2.757 7.535,1.293 C 5.812,-0.431 3.017,-0.431 1.293,1.293 C -0.431,3.017 -0.431,5.812 1.293,7.536 C 2.757,8.999 4.988,9.206 6.685,8.185 L 10.209,11.710 L 11.711,10.209 Z&quot;</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">=&quot;0,0,5,0&quot;&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Path.RenderTransform</span><span style="color: #0000ff">&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">ScaleTransform</span><span style="color: #ff0000"> ScaleX</span><span style="color: #0000ff">=&quot;2.5&quot;</span><span style="color: #ff0000"> ScaleY</span><span style="color: #0000ff">=&quot;2.5&quot; /&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Path.RenderTransform</span><span style="color: #0000ff">&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Path</span><span style="color: #0000ff">&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> Foreground</span><span style="color: #0000ff">=&quot;White&quot;</span><span style="color: #ff0000"> Text</span><span style="color: #0000ff">=&quot;Find Me Now&quot;</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">=&quot;20 -5 0 0&quot; /&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">&gt;</span> </li> <li>&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Button.Content</span><span style="color: #0000ff">&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Button</span><span style="color: #0000ff">&gt;</span> </li> </ol> </div> </div> </div> <p>&#160;</p> <p>Then and add a map layer with a simple circle pushpin to the map control:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:18eaa986-4cba-4662-9589-310a106f3c53" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; max-height: 100px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">m</span><span style="color: #0000ff">:</span><span style="color: #a31515">Map</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;mapMain&quot;</span><span style="color: #ff0000"> NavigationVisibility</span><span style="color: #0000ff">=&quot;Collapsed&quot;</span><span style="color: #ff0000"> Mode</span><span style="color: #0000ff">=&quot;AerialWithLabels&quot;</span><span style="color: #ff0000"> CredentialsProvider</span><span style="color: #0000ff">=&quot;ApXw1_p4abRAyITXFZGy6IvPyUN05hwF08hfkkNMUfExuujgB-XpmebygnDRH1RA&quot;&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">m</span><span style="color: #0000ff">:</span><span style="color: #a31515">MapLayer</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;lMain&quot;&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Ellipse</span><span style="color: #ff0000"> Fill</span><span style="color: #0000ff">=&quot;Red&quot;</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">=&quot;20&quot;</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">=&quot;20&quot;</span><span style="color: #ff0000"> m</span><span style="color: #0000ff">:</span><span style="color: #ff0000">MapLayer.Position</span><span style="color: #0000ff">=&quot;0,0&quot;</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;ppLocation&quot;</span><span style="color: #ff0000"> Visibility</span><span style="color: #0000ff">=&quot;Collapsed&quot; /&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">m</span><span style="color: #0000ff">:</span><span style="color: #a31515">MapLayer</span><span style="color: #0000ff">&gt;</span><span style="color: #a31515"></span> </li> <li><span style="color: #a31515">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">m</span><span style="color: #0000ff">:</span><span style="color: #a31515">Map</span><span style="color: #0000ff">&gt;</span><span style="color: #a31515"></span> </li> </ol> </div> </div> </div> <p>Now we are going to wire up the click event of the button to get the users location and update the map. We will do this in a number of stages.</p> <p>Firstly, add these using statements to the top of your code:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cd5aeb9b-4097-4cd1-8224-54e401118b6b" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #0000ff">using</span> System.Device.Location; </li> <li style="background: #f3f3f3"><span style="color: #0000ff">using</span> Microsoft.Maps.MapControl; </li> </ol> </div> </div> </div> <p>&#160;</p> <p>Now add a private member of type <em>GeoCoordinateWatcher</em> above the MainPage constructor:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:440aa7ac-af5b-4dad-af82-06e4352c7c3e" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; max-height: 200px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #2b91af">GeoCoordinateWatcher</span> watcher; </li> <li style="background: #f3f3f3"><span style="color: #0000ff">public</span> MainPage() </li> <li>{ </li> <li style="background: #f3f3f3">&#160;&#160;&#160; InitializeComponent(); </li> <li>&#160; </li> <li style="background: #f3f3f3">&#160;&#160;&#160; SupportedOrientations = <span style="color: #2b91af">SupportedPageOrientation</span>.Portrait | <span style="color: #2b91af">SupportedPageOrientation</span>.Landscape; </li> <li>} </li> </ol> </div> </div> </div> <p>And add the following event handler for the button click:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bd1be9da-9d1c-44a1-b0a1-e5d6b3c84ec3" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> btnStart_Click(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RoutedEventArgs</span> e) </li> <li style="background: #f3f3f3">{ </li> <li>&#160;&#160;&#160; <span style="color: #008000">// Reinitialize the GeoCoordinateWatcher</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; watcher = <span style="color: #0000ff">new</span> <span style="color: #2b91af">GeoCoordinateWatcher</span>(<span style="color: #2b91af">GeoPositionAccuracy</span>.High); </li> <li>&#160;&#160;&#160; watcher.MovementThreshold = 100;<span style="color: #008000">//distance in metres</span> </li> <li style="background: #f3f3f3">&#160; </li> <li>&#160;&#160;&#160; <span style="color: #008000">// Add event handlers for StatusChanged and PositionChanged events</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; watcher.StatusChanged += <span style="color: #0000ff">new</span> <span style="color: #2b91af">EventHandler</span>&lt;<span style="color: #2b91af">GeoPositionStatusChangedEventArgs</span>&gt;(watcher_StatusChanged); </li> <li>&#160;&#160;&#160; watcher.PositionChanged += <span style="color: #0000ff">new</span> <span style="color: #2b91af">EventHandler</span>&lt;<span style="color: #2b91af">GeoPositionChangedEventArgs</span>&lt;<span style="color: #2b91af">GeoCoordinate</span>&gt;&gt;(watcher_PositionChanged); </li> <li style="background: #f3f3f3">&#160; </li> <li>&#160;&#160;&#160; <span style="color: #008000">// Start data acquisition</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; watcher.Start(); </li> <li>&#160; </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #008000">//hide button</span> </li> <li>&#160;&#160;&#160; btnStart.Visibility = <span style="color: #2b91af">Visibility</span>.Collapsed; </li> <li style="background: #f3f3f3">} </li> </ol> </div> </div> </div> <p>This creates a new <em>GeoCoordinateWatcher</em> when the button is clicked with the accuracy set to high, sets a movement threshold allowing movement by 100 metres before the application is alerted and attaches two events. The first event “<em>StatusChanged</em>” will fire when the status of the location data changes (like during initialisation and once we have a location) and the second event handles changes to the current location. We will add the handlers for both in a minute. Lastly we start the watcher and hide the button then wire it up in the XAML to our recently added button’s click event:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f63d76f7-f6c5-49a9-87ed-d089b4b1ac01" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; max-height: 300px; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Button</span><span style="color: #ff0000"> Name</span><span style="color: #0000ff">=&quot;btnStart&quot;</span> <span style="color: #ff0000">Click</span><span style="color: #0000ff">=&quot;btnStart_Click&quot;</span><span style="color: #ff0000"> Width</span><span style="color: #0000ff">=&quot;260&quot;</span><span style="color: #ff0000"> Height</span><span style="color: #0000ff">=&quot;40&quot;&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Button.Content</span><span style="color: #0000ff">&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">StackPanel</span><span style="color: #ff0000"> Orientation</span><span style="color: #0000ff">=&quot;Horizontal&quot;&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Path</span><span style="color: #ff0000"> Fill</span><span style="color: #0000ff">=&quot;White&quot;</span><span style="color: #ff0000"> Data</span><span style="color: #0000ff">=&quot;F1 M 2.339,6.489 C 1.193,5.343 1.193,3.485 2.339,2.339 C 3.485,1.192 5.344,1.193 6.489,2.339 C 7.635,3.485 7.635,5.343 6.489,6.489 C 5.344,7.636 3.485,7.636 2.339,6.489 Z M 11.711,10.209 L 8.185,6.684 C 9.207,4.986 9.000,2.757 7.535,1.293 C 5.812,-0.431 3.017,-0.431 1.293,1.293 C -0.431,3.017 -0.431,5.812 1.293,7.536 C 2.757,8.999 4.988,9.206 6.685,8.185 L 10.209,11.710 L 11.711,10.209 Z&quot;</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">=&quot;0,0,5,0&quot;&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">Path.RenderTransform</span><span style="color: #0000ff">&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">ScaleTransform</span><span style="color: #ff0000"> ScaleX</span><span style="color: #0000ff">=&quot;2.5&quot;</span><span style="color: #ff0000"> ScaleY</span><span style="color: #0000ff">=&quot;2.5&quot; /&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Path.RenderTransform</span><span style="color: #0000ff">&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Path</span><span style="color: #0000ff">&gt;</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;</span><span style="color: #a31515">TextBlock</span><span style="color: #ff0000"> Foreground</span><span style="color: #0000ff">=&quot;White&quot;</span><span style="color: #ff0000"> Text</span><span style="color: #0000ff">=&quot;Find Me Now&quot;</span><span style="color: #ff0000"> Margin</span><span style="color: #0000ff">=&quot;20 -5 0 0&quot; /&gt;</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">StackPanel</span><span style="color: #0000ff">&gt;</span> </li> <li>&#160;&#160;&#160; <span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Button.Content</span><span style="color: #0000ff">&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #a31515"></span><span style="color: #0000ff">&lt;/</span><span style="color: #a31515">Button</span><span style="color: #0000ff">&gt;</span> </li> </ol> </div> </div> </div> <p>&#160;</p> <p>Ok, the next piece of the puzzle is to add the event handlers we attached in the button click handler above,<em> watcher_StatusChanged</em> and <em>watcher_PositionChanged</em>:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:20c3d9b8-c560-49f0-b5e7-e7ccc359b560" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #0000ff">#region</span> Event Handlers </li> <li style="background: #f3f3f3">&#160; </li> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;summary&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> Handler for the StatusChanged event. This invokes MyStatusChanged on the UI thread and</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> passes the GeoPositionStatusChangedEventArgs</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;/summary&gt;</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;param name=&quot;e&quot;&gt;&lt;/param&gt;</span> </li> <li><span style="color: #0000ff">void</span> watcher_StatusChanged(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">GeoPositionStatusChangedEventArgs</span> e) </li> <li style="background: #f3f3f3">{ </li> <li>&#160;&#160;&#160; <span style="color: #2b91af">Deployment</span>.Current.Dispatcher.BeginInvoke(() =&gt; MyStatusChanged(e)); </li> <li style="background: #f3f3f3">&#160; </li> <li>} </li> <li style="background: #f3f3f3">&#160; </li> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;summary&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> Handler for the PositionChanged event. This invokes MyStatusChanged on the UI thread and</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> passes the GeoPositionStatusChangedEventArgs</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;/summary&gt;</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;param name=&quot;e&quot;&gt;&lt;/param&gt;</span> </li> <li><span style="color: #0000ff">void</span> watcher_PositionChanged(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">GeoPositionChangedEventArgs</span>&lt;<span style="color: #2b91af">GeoCoordinate</span>&gt; e) </li> <li style="background: #f3f3f3">{ </li> <li>&#160;&#160;&#160; <span style="color: #2b91af">Deployment</span>.Current.Dispatcher.BeginInvoke(() =&gt; MyPositionChanged(e)); </li> <li style="background: #f3f3f3">} </li> <li>&#160; </li> <li style="background: #f3f3f3"><span style="color: #0000ff">#endregion</span> </li> </ol> </div> </div> </div> <p>You will notice these call two methods when they are triggered, but they ensure that these methods are called on the UI thread otherwise we will get some nasty cross thread errors.</p> <p>Finally add the two UI thread methods for doing something when the events fire, and a simple <em>ResetMap</em> method that's called when the user initially clicks the button:</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e245584f-c1bf-40f2-8d7b-d1708ad8d070" class="wlWriterSmartContent"> <div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; color: #000; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid"> <div style="background: #fff; overflow: auto"> <ol style="padding-bottom: 0px; margin: 0px; padding-left: 5px; padding-right: 0px; white-space: nowrap; background: #ffffff; padding-top: 0px"> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;summary&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> Custom method called from the PositionChanged event handler</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;/summary&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;param name=&quot;e&quot;&gt;&lt;/param&gt;</span> </li> <li><span style="color: #0000ff">void</span> MyPositionChanged(<span style="color: #2b91af">GeoPositionChangedEventArgs</span>&lt;<span style="color: #2b91af">GeoCoordinate</span>&gt; e) </li> <li style="background: #f3f3f3">{ </li> <li>&#160;&#160;&#160; <span style="color: #008000">// Update the map to show the current location</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #2b91af">Location</span> ppLoc = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Location</span>(e.Position.Location.Latitude, e.Position.Location.Longitude); </li> <li>&#160;&#160;&#160; mapMain.SetView(ppLoc, 10); </li> <li style="background: #f3f3f3">&#160; </li> <li>&#160;&#160;&#160; <span style="color: #008000">//update pushpin location and show</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #2b91af">MapLayer</span>.SetPosition(ppLocation, ppLoc); </li> <li>&#160;&#160;&#160; ppLocation.Visibility = System.Windows.<span style="color: #2b91af">Visibility</span>.Visible; </li> <li style="background: #f3f3f3">&#160; </li> <li>&#160;&#160;&#160;&#160; </li> <li style="background: #f3f3f3">} </li> <li>&#160; </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;summary&gt;</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> Custom method called from the StatusChanged event handler</span> </li> <li style="background: #f3f3f3"><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;/summary&gt;</span> </li> <li><span style="color: #808080">///</span><span style="color: #008000"> </span><span style="color: #808080">&lt;param name=&quot;e&quot;&gt;&lt;/param&gt;</span> </li> <li style="background: #f3f3f3"><span style="color: #0000ff">void</span> MyStatusChanged(<span style="color: #2b91af">GeoPositionStatusChangedEventArgs</span> e) </li> <li>{ </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #0000ff">switch</span> (e.Status) </li> <li>&#160;&#160;&#160; { </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">case</span> <span style="color: #2b91af">GeoPositionStatus</span>.Disabled: </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// The location service is disabled or unsupported.</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Alert the user</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tbStatus.Text = <span style="color: #a31515">&quot;sorry we can't find you on this device&quot;</span>; </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">break</span>; </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">case</span> <span style="color: #2b91af">GeoPositionStatus</span>.Initializing: </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// The location service is initializing.</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Disable the Start Location button</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tbStatus.Text = <span style="color: #a31515">&quot;looking for you...&quot;</span>; </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">break</span>; </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">case</span> <span style="color: #2b91af">GeoPositionStatus</span>.NoData: </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// The location service is working, but it cannot get location data</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Alert the user and enable the Stop Location button</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tbStatus.Text = <span style="color: #a31515">&quot;can't find you yet...&quot;</span>; </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ResetMap(); </li> <li>&#160; </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">break</span>; </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">case</span> <span style="color: #2b91af">GeoPositionStatus</span>.Ready: </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// The location service is working and is receiving location data</span> </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">// Show the current position and enable the Stop Location button</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tbStatus.Text = <span style="color: #a31515">&quot;found you!&quot;</span>; </li> <li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">break</span>; </li> <li style="background: #f3f3f3">&#160; </li> <li>&#160;&#160;&#160; } </li> <li style="background: #f3f3f3">} </li> <li>&#160; </li> <li style="background: #f3f3f3"><span style="color: #0000ff">void</span> ResetMap() </li> <li>{ </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #2b91af">Location</span> ppLoc = <span style="color: #0000ff">new</span> <span style="color: #2b91af">Location</span>(0, 0); </li> <li>&#160;&#160;&#160; mapMain.SetView(ppLoc, 1); </li> <li style="background: #f3f3f3">&#160; </li> <li>&#160;&#160;&#160; <span style="color: #008000">//update pushpin location and show</span> </li> <li style="background: #f3f3f3">&#160;&#160;&#160; <span style="color: #2b91af">MapLayer</span>.SetPosition(ppLocation, ppLoc); </li> <li>&#160;&#160;&#160; ppLocation.Visibility = System.Windows.<span style="color: #2b91af">Visibility</span>.Collapsed; </li> <li style="background: #f3f3f3">} </li> </ol> </div> </div> </div> <p>&#160;</p> <p>These first method <em>MyPositionChanged</em> updates the map by setting the current map view to the new location and zooming in. It also makes the pushpin icon visible. The second method <em>MyStatusChanged</em> simply updates the status text in the UI with a message telling the user the current state of the location services.</p> <h3>Houston we have a problem</h3> <p>By now you should have a finished application the compiles, if not you can download the source code below to see the full code:</p> <p><a href="http://earthware-website.azurewebsites.net/Content/images/wp-images/2010/03/BingMapsLocationAware.zip"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="butdownloadcode[1]" border="0" alt="butdownloadcode[1]" src="http://earthware-website.azurewebsites.net/Content/images/wp-images/2010/03/butdownloadcode1.gif" width="169" height="37" /></a></p> <p>You can run the application in the emulator by clicking F5 and the map and UI should appear, <strong>BUT</strong> here we find a problem.</p> <p>The emulator currently <strong>does not support the location service</strong>, so all we ever get back is a status change of <em>NoData</em>. There is currently not even any way to add fake data to the emulator so we will have to wait for an update to allow us to actually get location aware applications working in the emulator :-(</p> <p><strong>So until we can get our hands on some real hardware “Nudge, Nudge”&#160; there is no real way to test this application.</strong></p>
Close chatbot
Open chatbot
Open chatbot