-
Windows Phone 7.8 SDK released
Yesterday evening Microsoft has released an update for the Windows Phone SDK to support Windows Phone 7.8, that is the new version of the OS that will be released soon for the devices of the previous generation. Since Windows Phone 8, due to the new kernel, isn’t available as update for the current devices, Microsoft has decided to release an “intermediate” version, that will introduce some of the new Windows Phone 8 features in the current generation’s devices.
Most of the new features are for consumers: support to new tiles templates and sizes, Bing integration as a lock screen provider and so on.
From a developer point of view, nothing changes: there are no new APIs or features that can be used by the developer. The only news is the support to new tiles templates and sizes also for third party applications. To use them, however, there aren’t new APIs, but you have to use reflection: the system’s DLL that is able to interact with the tiles is loaded at runtime and, if the application is running on a Windows Phone 7.8 device, you are able to use them to support the new tiles.
The easiest way to take advantage of this feature is using Mangopollo, a library which I’ve talked you about in another post. This library “hides” the reflection mechanism by offering to the developer a high level API, that works in the same way of the original APIs that are available in Windows Phone 8.
Since there are no new APIs, which is the purpose of a new SDK? First, it’s not really a new SDK, but a patch, that is compatible both with the 7.1 SDK (if you don’t already have the 7.1.1 update, it’s included in this new release) and with the 8.0 SDK. This update will add to the existing list of available emulators two new images both based on Windows Phone 7.8: one standard and one with 256 MB of RAM, to simulate the low cost devices on the market.
You can download the update from the following address: http://www.microsoft.com/en-us/download/details.aspx?id=36474
in
-
Maps in Windows Phone 8 and Phone toolkit: a winning team – Part 2
In the last post we introduced the helpers that are available in the Phone toolkit for the Map control in Windows Phone 8: the map control is much more powerful than the one that is available in Windows Phone 7, but it lacks some controls that were widely used, like pushpins. In the previous post we’ve seen how to add a pushpin and place it in a specific position: it was an interesting experiment, but not really useful, because most of the times we need to place many pushpins on the same layer.
Let’s see how to do it using some features that every Windows Phone developer should know: template and binding.
Back to work
Let’s imagine that we’re going to display some restaurants that are near the user’s location. For this reason, the first thing we need is a class to map this information:
public class Restaurant { public GeoCoordinate Coordinate { get; set; } public string Address { get; set; } public string Name { get; set; } }
After that, we need a way to define a template to display a collection of Restaurant’s object over the map: we’re going to use one of the helpers available in the toolkit.
<maps:Map x:Name="myMap"> <toolkit:MapExtensions.Children> <toolkit:MapItemsControl Name="RestaurantItems"> <toolkit:MapItemsControl.ItemTemplate> <DataTemplate> <toolkit:Pushpin GeoCoordinate="{Binding Coordinate}" Content="{Binding Name}" /> </DataTemplate> </toolkit:MapItemsControl.ItemTemplate> </toolkit:MapItemsControl> </toolkit:MapExtensions.Children> </maps:Map>
We use again the MapExtensions.Children that we’ve learned to use in the previous post. Then we introduce the MapItemsControl, which is a control that is able to display a collection of objects over the map. Think of it like a ListBox control, but in this case the elements that are part of the collection are displayed over the map, as a new layer. The most interesting feature of this control is that, like other controls that are used to display collections, it supports templating: we can define the template (the ItemTemplate property) of a single object, that will be used to render every object that is part of the collection. In this sample, we define as a template a Pushpin object, which Content and GeoCoordinate properties are in binding with the properties of the Restaurant class. This means that, in the code, we’re going to assign to the ItemSource property of the MapItemsControl a collection of restaurants: the control is going to render a Pushpin for every restaurant in the collection and will place it on the map, in the position defined by the GeoCoordinate property.
Here is how we do it:
public MainPage() { InitializeComponent(); Loaded+=MainPage_Loaded; } void MainPage_Loaded(object sender, RoutedEventArgs e) { ObservableCollection<Restaurant> restaurants = new ObservableCollection<Restaurant>() { new Restaurant { Coordinate = new GeoCoordinate(47.6050338745117, -122.334243774414), Address = "Ristorante 1" }, new Restaurant() { Coordinate = new GeoCoordinate(47.6045697927475, -122.329885661602), Address = "Ristorante 2" }, new Restaurant() { Coordinate = new GeoCoordinate(47.605712890625, -122.330268859863), Address = "Ristorante 3" }, new Restaurant() { Coordinate = new GeoCoordinate(47.6015319824219, -122.335113525391), Address = "Ristorante 4" }, new Restaurant() { Coordinate = new GeoCoordinate(47.6056594848633, -122.334243774414), Address = "Ristorante 5" } }; ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(myMap); var obj = children.FirstOrDefault(x => x.GetType() == typeof(MapItemsControl)) as MapItemsControl; obj.ItemsSource = restaurants; myMap.SetView(new GeoCoordinate(47.6050338745117, -122.334243774414), 16); }
The first thing to highlight is that we’re going to use this code in the Loaded event of the page. This is required because, if we do it in the MainPage constructor, we risk that the code is executed before that every control in the page is rendered, so we may not have access yet to the MapItemsControl object.
First we create some fake restaurants to use for our test and we add it to a collection, which type is **ObservableCollection
.** Then we need to get a reference to the **MapItemsControl** object we’ve declared in the XAML, the one called **RestaurantItems.** Unlucky, due to the particular architecture of the **MapExtensions** helper provided with the toolkit, we can’t access to the control directly using the Name property, but we need to look for it in the collection of controls inside the **Children** property of the **MapExtensions** controls. To do this, we use the MapExtensions.GetChildren method of the toolkit, passing as parameter our map control. This method returns an **ObservableCollection
**, which is a collection of all the controls that have been added. In this case, by using ****a LINQ query and the **GetType()** method, we get a reference to the **MapItemsControl** object. We can use the **FirstOrDefault** statement because we’ve added just one **MapItemsControl** inside the **MapExtensions.Children** collection: once we have a reference, we cast it to the **MapItemsControl** (otherwise it would be a generic object, so we wouldn’t have access to the specific properties of the **MapItemsControl** class). Finally, we are able to access to the **ItemsSource** property, which holds the collection that is going to be displayed over the map using the **ItemTemplate** we’ve defined in the XAML: we simply assign to this property the fake **ObservableCollection ** we’ve created before. For sake of simplicity, we also set the center of the map to the coordinates of the first restaurant: this way will be easier for us to test the code and see if every pushpin is displayed correctly.
And here is the final result:
###
In the end
As you can see, the mechanism is very simple: it’s the usual one that we already use every time we have a collection that we wants to display. We define a collection of objects (usually a **ObservableCollection
,** to have INotifyPropertyChanged support out of the box), we define an **ItemTemplate** in the XAML and we assign the collection to the **ItemsSource** property of the control. The only trivial thing, in this case, is to get a reference to the **MapItemsControl** object, since it can’t be referenced just by using the name as for every other control. Here is the link to download a sample that recap most of the things we’ve seen in the latest two posts:
in
-
Maps in Windows Phone 8 and Phone toolkit: a winning team – Part 1
Maps in Windows Phone 8 is probably the biggest evidence of the great partnership between Nokia and Microsoft: in Windows Phone 8 the maps application installed on every device, even the ones made by other manufacturers, is powered by Nokia technologies.
The most interesting news for developers is that also the Maps control has been updated and it introduced many improvements: first of all, performance improvements. Bing Maps control wasn’t good in this and, especially if you tried to add layers or pushpin, you could have experienced really poor performances.
Second, the new control now offers lot of new options: you can enable 3D landmarks, you can switch between day and night colors, you can change the heading and the pitch, you can easily calculate routes and so on.
Adding the map control is very easy: in the XAML you need to add a reference to the Microsoft.Phone.Maps namespace:
xmlns:maps=”clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps”
After that you can insert the Map control simply by declaring it in the XAML:
<maps:Map x:Name="myMap" Center="30.712474,-132.32691" ZoomLevel="17" Heading="45" Pitch="25" CartographicMode="Road" ColorMode="Dark" PedestrianFeaturesEnabled="True" LandmarksEnabled="True" />
In this sample you can see an example of many of the properties that are available in the control:
- Center is the location where the map is centered. It accepts a GeoCoordinate object, which is a complex object that store many geo location properties, like latitude, longitude, altitude and so on.
- ZoomLevel is the zoom level of the map, from 1 (very far) to 20 (very near).
- Heading is the rotation of the map.
- Pitch is the elevation of the map compared to the horizon.
- CartographicMode is the type of map that is displayed, you can choose between Aerial, Road, Terrain or Hybrid.
- ColoreMode can be used to improve the readability of the map during night (Dark) and day (Light).
- LandmarksEnabled can be used to turn on the 3D representation of some important builidings in the map (like monuments, churches and so on).
- PedestrianFeaturesEnabled can be used to turn elements that are useful for people that is using the map during a walking (like stairs). </ul> One of the coolest feature is that, with the new map control, is really easy to add a layer, that is a collection of elements that are displayed over the map, as you can see in this sample:
private void OnAddShapeClicked(object sender, RoutedEventArgs e) { MapOverlay overlay = new MapOverlay { GeoCoordinate = myMap.Center, Content = new Ellipse { Fill = new SolidColorBrush(Colors.Red), Width = 40, Height = 40 } }; MapLayer layer = new MapLayer(); layer.Add(overlay);
- LandmarksEnabled can be used to turn on the 3D representation of some important builidings in the map (like monuments, churches and so on).
- ColoreMode can be used to improve the readability of the map during night (Dark) and day (Light).
- CartographicMode is the type of map that is displayed, you can choose between Aerial, Road, Terrain or Hybrid.
- Pitch is the elevation of the map compared to the horizon.
- Heading is the rotation of the map.
myMap.Layers.Add(layer); }
- ZoomLevel is the zoom level of the map, from 1 (very far) to 20 (very near).
</pre>
For every element I want to display on the map I create a **MapOverlay** object, that has two main properties: **GeoCoordinate**, with the coordinates where the element should be placed, and **Content**, which is a generic object property so it accepts any XAML control. In this example, I’m creating a blue circle, using the **Ellipse** control, that will be placed in the same position where the map is centered. In the end I simply create a **MapLayer** and I add to it the **MapOverlay** object I’ve just created: I could have created many more **MapOverlay** object and added them to the same **MapLayer** (or also to a new one). The last step is to add the layer to the map, by simply adding it to the **Layers** collection, which is a property of the **Map** control. Here is the final result: [<img title="shape" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="shape" src="https://i0.wp.com/wp.qmatteoq.com/wp-content/uploads/2013/01/shape_thumb.png?resize=222%2C370" width="222" height="370" data-recalc-dims="1" />](https://i0.wp.com/wp.qmatteoq.com/wp-content/uploads/2013/01/shape.png) This feature is very powerful: since the **MapOverlay** object has a generic **Content** property, you can customize the overlay elements any way you want. But there’s a downside: there’s nothing ready to be used in the SDK for common scenarios like displaying a pushpin or the user’s location. ### ### So please say hello to the **Phone Toolkit**, that probably you already know since it’s one of the essentials toolkits for every Windows Phone developers, since it contains many useful controls, helpers and converters that are not available in the SDK, even some of the standard ones that are used in the native application. The Phone Toolkit is available on <a href="http://phone.codeplex.com/" target="_blank">Codeplex</a>, but the easiest way to add it to your project is using <a href="https://nuget.org/packages/WPtoolkit" target="_blank">NuGet</a>. In the latest release Microsoft has added, other than some new cool controls and transitions effects, some map utilities. In our scenario we can make use of two nice controls: **UserLocationMarker** and **Pushpin**. They both work in the same way: they are overlay elements that are placed on the map over a specific position and they offer a way to interact with them (so that, for example, the user can tap on a pushpin and do something). They only **look** **different**: the **Pushpin** (in the left image) has the same look & feel of the ones that were available in the old Bing Maps and can be used to highlights point of interests in the map; **UserLocationMarker** (in the right image) is used to identify the position of the user and it has the same look & feel of the one used in the native app. [<img title="pushpin" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="pushpin" src="https://i1.wp.com/wp.qmatteoq.com/wp-content/uploads/2013/01/pushpin_thumb.png?resize=222%2C370" width="222" height="370" data-recalc-dims="1" />](https://i1.wp.com/wp.qmatteoq.com/wp-content/uploads/2013/01/pushpin.png)[<img title="user" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;margin: 0px 0px 0px 15px;border-left: 0px;padding-right: 0px" border="0" alt="user" src="https://i0.wp.com/wp.qmatteoq.com/wp-content/uploads/2013/01/user_thumb.png?resize=222%2C370" width="222" height="370" data-recalc-dims="1" />](https://i1.wp.com/wp.qmatteoq.com/wp-content/uploads/2013/01/user.png) ### How to use pushpins First let’s see the simplest way to add a single **Pushpin** or a **UserLocationMarker** to the map. First you have to declare in the XAML the following namespace: _xmlns:toolkit=”clr-namespace:Microsoft.Phone.Maps.Toolkit;assembly=Microsoft.Phone.Controls.Toolkit”_ Then here is a sample XAML: <pre class="brush: xml;"><maps:Map x:Name="myMap"> <toolkit:MapExtensions.Children> <toolkit:UserLocationMarker x:Name="UserLocationMarker" /> <toolkit:Pushpin x:Name="MyPushpin" Content="My Position"></toolkit:Pushpin> </toolkit:MapExtensions.Children> </maps:Map></pre> The first thing is to use the **MapExtensions**, one of the extensions available in the toolkit. This extension has a **Children** property, that is the collection of the elements that are displayed over the map. In this code you can see an example of both controls: **UserLocationMarker** and **Pushpin**. The only difference is that, for the pushpin, I’ve set the **Content** property, which is the label displayed on the mark. If we want to manage them in the code, in order to set the position in the map, we can use the following code: <pre class="brush: csharp;">UserLocationMarker marker = (UserLocationMarker)this.FindName("UserLocationMarker"); marker.GeoCoordinate = myMap.Center;
Pushpin pushpin = (Pushpin)this.FindName(“MyPushpin”); pushpin.GeoCoordinate = new GeoCoordinate(30.712474, -132.32691);
</pre>
First we retrieve the control by using the **FindName** method and passing as parameter the value of the **x:Name** property of the control. Then, once we have a reference, we change the value of the **GeoCoordinate** property. Both controls also have a **Tap** event, that is triggered when user taps on the pushpin. We can use it to interact with the user, like in the following example: <pre class="brush: xml;"><maps:Map x:Name="myMap" Height="400"> <toolkit:MapExtensions.Children> <toolkit:Pushpin x:Name="MyPushpin" Content="My Position" Tap="MyPushpin_OnTap" /> </toolkit:MapExtensions.Children> </maps:Map>
</pre>
<pre class="brush: csharp;">private void MyPushpin_OnTap(object sender, GestureEventArgs e) { Pushpin pushpin = sender as Pushpin; MessageBox.Show(pushpin.Content.ToString()); }</pre> In the XAML we have declared an event handler to manage the **Tap** event; in the code we get the pushpin that has been tapped (using the **sender** object that is passed as parameter) ****and we show the label on the screen using a MessageBox. ### ### A useful converter If you’ve already played with the geo localization services available in the new Windows Runtime APIs (the same that are available in Windows 8), you should have noticed a weird thing: the class used by the geo localization APIs to store location information is called **Geolocalization**, while the one used by the map is called **GeoLocalization**. Unlucky, it’s not a typo, they are two different classes: the result is that you can’t take the information returned by the geo localization APIs and assign it to the map, but you need a conversion. Luckily, the Phone Toolkit contains an extension method to do that, you simply have to add the **Microsoft.Phone.Maps.Toolkit** to the code and than you can do something like this: <pre class="brush: csharp;">Geolocator geolocator = new Geolocator(); Geoposition geoposition = await geolocator.GetGeopositionAsync(); myMap.Center = geoposition.Coordinate.ToGeoCoordinate();
</pre>
The **ToGeoCoordinate()** extension method takes care of converting the **Coordinate** object returned by the **Geolocator** class (which type is **Geocoordinate**) in the correct one required by the map control. ### ### In the next post In this post we’ve covered some basic scenarios: they are useful to understand how the phone toolkit can be helpful in developing an application that uses maps, but they are not so useful in a real scenario. For example, a real application would have displayed more than one pushpin in the map, in order to display, for example, some point of interests around the user, like restaurants or pubs. In the next post we’ll see how to do that using some concepts every Windows Phone developer should be familiar with: templates and binding.
in
- Center is the location where the map is centered. It accepts a GeoCoordinate object, which is a complex object that store many geo location properties, like latitude, longitude, altitude and so on.
subscribe via RSS