Back

TechnologyNov 01, 2011

Building Interactive Maps with Silverlight and Bing Maps

Kevin King

overview

The goal of this blog is to detail each step in the process of creating a functioning Silverlight application using Bing maps. This will also be the first of a series of blogs that explore the versatility and extendibility of this application to other Microsoft technology platforms including SharePoint, CRM, and ASP.NET.

We will be leveraging the following tools and technologies.

  • Visual Studio 2010

  • Silverlight 4

  • Bing Maps Silverlight Control SDK

Overview of steps:

  1. Create a new solution in Visual Studio

  2. Add references to the Bing Maps Silverlight Control API

  3. Create map control

  4. Create Silverlight UI controls

  5. Connect the map to a data source

  6. Handle user input and plot map pushpins

step 1 – create a new solution in visual studio

To begin, we will create a new Visual Studio project. When prompted, select “Silverlight Application” as the project type and give it a name. For this demo, I have named the project BingMapsDemo.

After clicking “Ok”, you will be asked where you’d like to host this new Silverlight application. For our purposes, we want to “Host the Silverlight application in a new Web Site”. Also, while we won’t be exploring WCF RIA Services in this blog, we will want to enable them for future how-to’s that will build on this application.

After we click “Ok”, our solution is created. You should see two projects, one that is the actual Silverlight project (BingMapsDemo), and the other that is an ASP.NET website (BingMapsDemo.Web) that will be the host for the Silverlight application.

step 2 – add references to the bing maps silverlight control api

Next, we want to add a reference to the Bing Maps Silverlight Control API. To do this, in our Silverlight application, right click on References and click “Add Reference”.

When the Add Reference dialog panel shows up, click the “Browse” tab and navigate to where your Bing Maps Control API was downloaded. The default path will look something like this:

C:\Program Files (x86)\Bing Maps Silverlight Control\V1\Libraries

Select both dll files and click “OK”. Now we have properly referenced the Bing Maps Silverlight Control API.

step 3 – create the map control

First, open the MainPage.xaml page from our solution explorer.

Our code will look like this before we do any editing.

<UserControl x:Class="BingMapsDemo.MainPage"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   mc:Ignorable="d"    d:DesignHeight="600" d:DesignWidth="800">

<Grid x:Name="LayoutRoot" Background="White">

</Grid> </UserControl>

In order to add the Bing Maps control, we must create a prefix reference to use as an alias for the API. Here is our code with the “bing” alias created.

<UserControl x:Class="BingMapsDemo.MainPage"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"     xmlns__:bing="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"__    mc:Ignorable="d"    d:DesignHeight="600" d:DesignWidth="800">

<Grid x:Name="LayoutRoot" Background="White">

</Grid> </UserControl>

Now, we can use this alias to create our Bing Maps control. We will add the code directly to our LayoutRoot grid.

<Grid x:Name="LayoutRoot" Background="White"> <bing:Map Name="MyMap"/> </Grid>

By default, our map will take up the entire grid, but we can give it a set height and width if we want. Before we can move forward, we must create a development Bing Maps application key.

If you do not have a Bing Maps account, you can create one here: http://www.bingmapsportal.com/

Once you have created an account, you can go here to create an application key: https://www.bingmapsportal.com/application/index/1008811?status=NoStatus

Because this is a test application, it doesn’t matter what information you provide. Once you’ve submitted your request for an application key, you will see it show up below this form with the full key.

Now we can add this key into our control and we will see the map. At this point, we are ready to add map icons to the map to show business data.

<Grid x:Name="LayoutRoot" Background="White"> <bing:Map Name="MyMap" CredentialsProvider="Your key here" /> </Grid>

In the designer pane of Visual Studio, we see our empty map.

step 4 – create the silverlight ui controls

For this demo, we will take a minimalistic approach to the non-map user controls. Our main goal is to plot geospatial data on the map, but we will add a small layer of complexity by requesting some input from our user. For this demo, we will work under the guise of a travelling computer salesman. Our salesman has customers all across the United States. We will use this demo to show him where his PC and Mac users are on the map. Later, we will add other data filtering options as our application grows.

For our user input control section, we will add a label, a drop-down list (called a ComboBox in Silverlight), and a button to “Load” our customers on the map. Later, we will learn about control templating and styling, but for simplicity I have included all customization inline to each control. Here is the code for our new section.

<Border Background="SteelBlue" Width="250" Height="Auto" HorizontalAlignment="Right"             VerticalAlignment="Top" CornerRadius="10" Margin="10" Padding="10"> <StackPanel Orientation="Vertical" > <StackPanel Orientation="Horizontal"> <TextBlock Text="Computer Type" Foreground="White" FontSize="15"                             Margin="0,0,10,0" HorizontalAlignment="Left" /> <ComboBox Name="cbCompType" Width="100" HorizontalAlignment="Right"> <ComboBoxItem FontSize="15" IsSelected="True">-All-</ComboBoxItem> <ComboBoxItem FontSize="15">PC</ComboBoxItem> <ComboBoxItem FontSize="15">Mac</ComboBoxItem> </ComboBox> </StackPanel>

</StackPanel> </Border>

Our map now looks like this:

Transform your business operations with our Microsoft solutions

Explore Our Microsoft Consulting Services  →

step 5 – connect the map to a data source

First, let’s create the model for our customer. Create a class file called Customer.cs and insert the following code. We will want to filter based on the customer’s name and their volume. We will need the latitude and longitude to plot them on the map.

We are inheriting from the Bing Maps class “Pushpin”, which will allow us to directly add our customers to the map. We are extending it to include our business attributes, CustomerName and CustomerType.

In the class constructor, based on the type of computer, we set the background color for our Customer, which tells the underlying pushpin graphic what color to be. This is convenient because we let Bing handle all of the rendering and we can perform our business logic at the same time. We also set the hover tooltip to the name of the customer.

using Microsoft.Maps.MapControl;

namespace BingMapsDemo {     public class Customer : Pushpin     {         public string CustomerName { get; set; }         public string ComputerType { get; set; }

        public Customer(string name, string type, double lat, double lon)         {             this.CustomerName = name;             this.ComputerType = type;             this.Location = new Location(lat, lon);             ToolTipService.SetToolTip(this, name);             if (type == "Mac")             {                 this.Background = new SolidColorBrush(Colors.Blue);             }             else             {                 this.Background = new SolidColorBrush(Colors.Green);             }         }     } }

Now that we have created our Customer class, we can instantiate a few and create our dummy data source. In later blogs, we will connect to actual data sources to populate our list of Customers.

In MainPage.xaml.cs, we add the following code the the MainPage() constructor. First, we set the center of our map to the United States, and set a proper zoom level to see the entire country. Then, we create a few customers and add them to our page property Customers. In later blogs, we will discuss the MVVM pattern to decouple our data source, business logic, and UI, but for now we will keep everything on the MainPage for simplicity.

using Microsoft.Maps.MapControl;

namespace BingMapsDemo {     public partial class MainPage : UserControl     {         public List<Customer> Customers { get; set; }

        public MainPage()         {             InitializeComponent();

            MyMap.Center = new Location(39.226, -99.829);             MyMap.ZoomLevel = 5;

            Customers = new List<Customer>();             Customers.Add(new Customer("Bill", "PC", 37, -79));             Customers.Add(new Customer("Steve", "Mac", 30, -90));             Customers.Add(new Customer("Maria", "PC", 45, -92));             Customers.Add(new Customer("Andy", "Mac", 45, -108));             Customers.Add(new Customer("Tiffany", "PC", 40, -118));             Customers.Add(new Customer("Ryan", "PC", 35, -102));         }     } }

Now that we have a list of Customers in the Silverlight application memory, we can wire up our user controls to filter what is being displayed on the map.

First, we want to create an event for our button we added previously. We will add an event handler to the button we have on our map.

<Button Name="btnLoadCustomers" Content="Load Customers" Margin="0,10,0,0" Width="175"             FontSize="15"  HorizontalAlignment="Right" Click="btnLoadCustomers_Click" />

Then, in the event handler that is created in the code behind, we want to add code that checks the computer type ComboBox (drop-down list) to add the correct customers to the map. It is important to clear out the customers that are already on the map to avoid duplicates and customers that don’t belong. If the user selects “-All-“, we add the customer regardless of computer type.

    private void btnLoadCustomers_Click(object sender, RoutedEventArgs e)     {         MyMap.Children.Clear();         ComboBoxItem item = cbCompType.SelectedItem as ComboBoxItem;         string compType = item.Content.ToString();

        foreach (Customer cust in Customers)         {             if (cust.ComputerType == compType)                 MyMap.Children.Add(cust);             else if (compType == "-All-")                 MyMap.Children.Add(cust);         }     }

That’s it! Run the application and see your data on an interactive Silverlight mapping application.