Infoboxes for Native Windows Store Apps

Recently there has been a number of requests for information on how to create infoboxes using the Bing Maps Native control. Many developers who have used our JavaScript controls are used to an infobox control being available out of the box and are a bit surprised that there isn’t one in the Native control. This wasn’t an oversight, but really not needed. With the Native control, we have the ability to overlay user controls directly on top of the map and tie them to a location on the map. This means that rather than being restricted to having to use an infobox control that looks and feels the way we think it should, you have the ability to create an infobox that looks and feels how you want.

In this blog post we will take a look at how to create a simple infobox control. To optimize this application, we will use a common method of having one Infobox control which we will reuse and update rather than creating an infobox for each pushpin we create. This will drastically reduce the number of objects your application will need to render and keep track of. This same approach is recommended when using the JavaScript control as well. If using JavaScript, take a look at this blog post.

Creating the View

To start off, create a Blank Windows Store project in Visual Studio called BingMaps_Native_Infobox and add a reference to the Bing Maps SDK. If you are not familiar with how to do this, take a look at the Getting started with Bing Maps Windows Store Apps (Native) blog post.

Once your project is created, open up the MainPage.xaml file and add a reference to the Bing Maps SDK and add a map to the main Grid. Inside of the map, we will add two MapLayers and give the first layer a name of DataLayer. We will use this layer to add our pushpins to. We will put the infobox in the second layer and this will ensure that the infobox always appears above the data layer. For the infobox itself, we will use a Grid control and add some Textboxes for Title and Description information. We will also add a close button to the infobox. Putting this together, your XAML should look like this:

<Page
x:Class="BingMaps_Infoboxes_Native.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BingMaps_Infoboxes_Native"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:Bing.Maps"
mc:Ignorable="d">

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<m:Map Credentials="YOUR_BING_MAPS_KEY">
<m:Map.Children>
<!-- Data Layer-->
<m:MapLayer Name="DataLayer"/>

<!--Common Infobox-->
<m:MapLayer>
<Grid x:Name="Infobox" Visibility="Collapsed" Margin="0,-115,-15,0">                        
<Border Width="300" Height="110" Background="Black" Opacity="0.8" BorderBrush="White" BorderThickness="2" CornerRadius="5"/>

<StackPanel Height="100" Margin="5">
<Grid Height="40">
<TextBlock Text="{Binding Title}" FontSize="20" Width="250" TextWrapping="Wrap" HorizontalAlignment="Left" />
<Button Content="X" Tapped="CloseInfobox_Tapped" HorizontalAlignment="Right" VerticalAlignment="Top"/>
</Grid>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" MaxHeight="60">
<TextBlock Text="{Binding Description}" FontSize="16" Width="290" TextWrapping="Wrap" Height="Auto"/>
</ScrollViewer>
</StackPanel>
</Grid>
</m:MapLayer>
</m:Map.Children>
</m:Map>
</Grid>
</Page>

Adding the Application Logic

If you try running the application now, an error will be thrown as we haven’t defined the CloseInfobox_Tapped event handler. To fix this, open the MainPage.xaml.cs file and add the following event handler:

 
private void CloseInfobox_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
    Infobox.Visibility = Visibility.Collapsed;
}

Next, we need to add some pushpins to the map. To do this, we will create a reusable function that takes in a Location, title, description and a reference to a MapLayer to add the pushpin to. When we create the pushpin we will store the title and description inside the Tag property of the pushpin. We will then add a Tapped event which we will use to open our infobox. Finally, we will add the pushpin to the layer. Add the following code to your application:

public void AddPushpin(Location latlong, string title, string description, MapLayer layer)
{
    Pushpin p = new Pushpin()
    {
        Tag = new Metadata()
        {
            Title = title,
            Description = description
        }
    };

    MapLayer.SetPosition(p, latlong);

    p.Tapped += PinTapped;

    layer.Children.Add(p);
}

public class Metadata
{
public string Title { get; set; }
public string Description { get; set; }
}

Now we will create the PinTapped event handler. When the user taps the pushpin, we will take the metadata we stored in the pushpin and bind it to the Infobox. We will then make the infobox visibility and then use the MapLayer to set the position of the infobox.

private void PinTapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
    Pushpin p = sender as Pushpin;
    Metadata m = (Metadata)p.Tag;

//Ensure there is content to be displayed before modifying the infobox control
if (!String.IsNullOrEmpty(m.Title) || !String.IsNullOrEmpty(m.Description))
    {
        Infobox.DataContext = m;

        Infobox.Visibility = Visibility.Visible;

        MapLayer.SetPosition(Infobox, MapLayer.GetPosition(p));
    }
else
    {
        Infobox.Visibility = Visibility.Collapsed;
    }
}

We now have all the code we need to create pushpins that open up an Infobox when tapped. All we need to do now is create some pushpins. To do this, update the constructor to look like this:

public MainPage()
{
this.InitializeComponent();

    AddPushpin(new Location(47.6035, -122.3294), "Seattle", "Seattle is in the state of Washington. ", DataLayer);

    AddPushpin(new Location(51.5063, -0.1271), "London", "London is the capital city of England and the United Kingdom, and the largest city in the United Kingdom.", DataLayer);
}

If you run the application, you will see two pushpins on the map. If you tap on one, the Infobox will appear with the relevant information for that pushpin and look something like this:

win8_infobox_thumb-1-(1).png

You can take this a step further and create a custom UserControl that has a lot more advanced features. In the end you simply just need to add it to a MapLayer and set its position.