Introduction

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.

However in this post i am going to explain about "How to add custom pushpin to MapView" and "How to show a custom tooltip for tapped pushpin"

Note: Please read about Maps API by following great links

1)Maps and navigations for windows phone 8

2)Guide to windows phone 8 Maps API

Building the Sample

Adding the map control is very easy: in the XAML you need to add a reference to theMicrosoft.Phone.Maps namespace:

 XAML

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:
XAML
<maps:Map  Name="MapVieMode" LandmarksEnabled="true"  PedestrianFeaturesEnabled="true" HorizontalAlignment="Left"  MinWidth="500" MinHeight="750"  VerticalAlignment="Top" 
Loaded="Map_Loaded" Background="Black"/>
Note: This sample is only working  with windows phone 8 sdk and above


Description

I’ve been working on a Windows Phone project which includes a lot of pushpins on Bing maps which carry information important to the user. Now, I wanted some form of interaction in the form of a tooltip ����� user can request more information about particular pushpin by tapping on it. Of course, the word tooltip might be misleading because it usually involves mouse pointer placed above a control for a short period of time before the tooltip gets shown. There is no such thing on Windows Phone like placing a mouse pointer over a control, but the effect can easily be accomplished on tap event. I’ll show you how to do it in this article. 

Now, let’s assume that we have a model called LocationDetail which holds the Pushpin object and some information about it, such as Name, Miles,Lat and Long when it was added to some imaginary database. This is how we could describe such a model:

 

C#
public class LocationDetail 
    { 
        public string id { getset; } 
        public string D_name { getset; } 
        public string Lat { getset; } 
        public string Long { getset; } 
        public string _number;  
        public string Distance 
        { 
            get 
            { 
                return this._number; 
            } 
            set 
            { 
                if (value != null) 
                { 
                     
                    this._number = value + " " + "miles"; 
                } 
                else 
                { 
                    this._number = value; 
                } 
            } 
        } 
         
    }
 Next we could Add items in which we’ll populate ObservableCollection with some LocationDetails:
C#
public class LocationList : List<LocationDetail>{} 
public List<GeoCoordinate> MyCoordinates = new List<GeoCoordinate>(); 
LocationList LocationListobj = new LocationList(); 
LocationListobj.Add(new LocationDetail { id = "1", D_name = "West Bank Office Building Ramp", Lat = "44.976288", Long = "-93.248582", Distance = "2" }); 
 
 LocationListobj.Add(new LocationDetail { id = "2", D_name = "19th Avenue Ramp", 
Lat = "44.970541", Long = "-93.246075", Distance = "3" }); 
 
LocationListobj.Add(new LocationDetail { id = "4", D_name = "Washington Avenue Ramp",
 Lat = "44.973919", Long = "-93.231372", Distance = "5" }); 
 
LocationListobj.Add(new LocationDetail { id = "5", D_name = "University Avenue Ramp", 
Lat = "44.976140", Long = "-93.228981", Distance = "6" }); 
 
 MapVieMode.Layers.Clear(); 
MapLayer mapLayer = new MapLayer(); 
MyCoordinates.Clear(); 
 for (int i = 0; i < LocationListobj.Count; i++) 
 { 
    MyCoordinates.Add(new GeoCoordinate { Latitude = double.Parse("" +
 LocationListobj[i].Lat), Longitude = double.Parse("" + LocationListobj[i].Long) }); 
 
}

How to create custom pushpin with user control

Step1:



Add mapview to your MainPage



XAML
 <maps:Map  Name="MapVieMode" LandmarksEnabled="true"  PedestrianFeaturesEnabled="true" HorizontalAlignment="Left"  MinWidth="500" MinHeight="750"  VerticalAlignment="Top" 
Loaded="Map_Loaded" Background="Black"/>
 Step2:
 
     Add the Silverlight for Windows Phone Toolkit to your project. I used NuGet for it. Reference it in the App.xaml:
XAML
xmlns:Toolkit= "clr-namespace:Microsoft.Phone.Controls;
assembly=Microsoft.Phone.Controls.Toolkit"
 In order to show the tooltip on pushpin tap event, we’ll used the ContextMenu available in Silverlight for Windows Phone Toolkit. Add it to our custom UserControl like this:
XAML
<UserControl  x:Class="CustomPushpinWp8.UCCustomToolTip" <StackPanel  HorizontalAlignment="Center" VerticalAlignment="Center" 
        <Image Tag="{Binding id}" Source="/Assets/MapPin.png" Stretch="None"  x:Name="imgmarker" HorizontalAlignment="Left"             <Toolkit:ContextMenuService.ContextMenu                <Toolkit:ContextMenu  IsZoomEnabled="True"  
                                        Style="{StaticResource MenuStyle}"                     <Toolkit:MenuItem Tag="{Binding id}" Name="Menuitem" 
                               Style="{StaticResource MenuItemStyle}" /> 
                </Toolkit:ContextMenu> 
            </Toolkit:ContextMenuService.ContextMenu> 
</Image> 
 </StackPanel> 
</UserControl>
 The MenuItemStyle should be defined in the App.xaml, and look (for example), like this:
XAML
<Application.Resources        <local:LocalizedStrings xmlns:local="clr-namespace:CustomPushpinWp8" x:Key="LocalizedStrings"/> 
        <Style x:Key="MenuItemStyle" TargetType="Toolkit:MenuItem"> 
            <Setter Property="Template"> 
                <Setter.Value> 
                    <ControlTemplate TargetType="Toolkit:MenuItem"> 
                        <StackPanel> 
                            <TextBlock Margin="5,0,0,0Foreground="Black"
                                      Text="{Binding D_name}"  
                                       TextWrapping="Wrap"  
                                       FontSize="26" 
                                       FontWeight="Bold"/> 
                            <TextBlock  Foreground="Black"  
 Text="{Binding Distance}"  
                                       TextTrimming="WordEllipsis"  
                                       Margin="5,0"  
                                       FontSize="22"/> 
 
                        </StackPanel> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
 
        <Style x:Key="MenuStyle" TargetType="Toolkit:ContextMenu"> 
            <Setter Property="Template"> 
                <Setter.Value> 
                    <ControlTemplate> 
                        <Border CornerRadius="8Margin="12,0,12,0"  
                               BorderBrush="BlueBorderThickness="2"> 
                            <Border.Background> 
                                <LinearGradientBrush  
                                   StartPoint="0.5,0EndPoint="0.5,1"> 
                                    <GradientStop Color="White"  
                                                 Offset="0.0"/> 
                                    <GradientStop Color="LightBlue"  
                                                 Offset="0.5"/> 
                                </LinearGradientBrush> 
                            </Border.Background> 
                            <ItemsPresenter /> 
                        </Border> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
    </Application.Resources>
 Step3: 
       Now we are completed Design part,And so that we need to add our custom usercontrol on mapview like this
C#
for (int i = 0; i < MyCoordinates.Count; i++) 
            { 
 
                //DrawMapMarker(MyCoordinates[i], Colors.Red, mapLayer,  parklist.parking_details[i].DestinationName); 
                UCCustomToolTip _tooltip = new UCCustomToolTip(); 
               _tooltip.Description = LocationListobj[i].D_name.ToString()
                   + "\n" + LocationListobj[i].Distance; 
                _tooltip.DataContext = LocationListobj[i]; 
                 _tooltip.Menuitem.Click += Menuitem_Click; 
                _tooltip.imgmarker.Tap += _tooltip_Tapimg; 
                MapOverlay overlay = new MapOverlay(); 
                overlay.Content = _tooltip; 
                overlay.GeoCoordinate = MyCoordinates[i]; 
                overlay.PositionOrigin = new Point(0.01.0); 
                mapLayer.Add(overlay); 
            } 
            MapVieMode.Layers.Add(mapLayer);

How to Show Custom Tooltip for Tapped Pushpin





  To show the ContextMenu ToolTip on Tap event, we’ll use the _tooltip_Tapimg event handler:
C#
 UCCustomToolTip _tooltip = new UCCustomToolTip(); 
_tooltip.imgmarker.Tap += _tooltip_Tapimg;
 
C#
 private void _tooltip_Tapimg(object sender, System.Windows.Input.GestureEventArgs e) 
        { 
            try 
            { 
                Image item = (Image)sender; 
                string selecteditem = item.Tag.ToString(); 
                var selectedparkdata = LocationListobj.Where(s => s.id == 
selecteditem).ToList(); 
 
 
                if (selectedparkdata.Count > 0) 
                { 
                    foreach (var items in selectedparkdata) 
                    { 
                        ContextMenu contextMenu = 
                    ContextMenuService.GetContextMenu(item); 
                        contextMenu.DataContext = items; 
                        if (contextMenu.Parent == null) 
                        { 
                            contextMenu.IsOpen = true; 
 
                        } 
                        break; 
                    } 
                } 
            } 
            catch 
            { 
            } 
        }

How to get Tapped ToolTip Details

C#
 UCCustomToolTip _tooltip = new UCCustomToolTip(); 
_tooltip.Menuitem.Click += Menuitem_Click;
 
C#
private void Menuitem_Click(object sender, RoutedEventArgs e) 
        { 
            try 
            { 
                MenuItem item = (MenuItem)sender; 
                string selecteditem = item.Tag.ToString(); 
                var selectedparkdata = LocationListobj.Where(s =>
 s.id == selecteditem).ToList(); 
                if (selectedparkdata.Count > 0) 
                { 
                    foreach (var items in selectedparkdata) 
                    { 
                         
                        if (Settings.FileExists("LocationDetailItem")) 
                        { 
                            Settings.DeleteFile("LocationDetailItem"); 
                        } 
                        using (IsolatedStorageFileStream fileStream = 
Settings.OpenFile("LocationDetailItem", FileMode.Create)) 
                        { 
                            DataContractSerializer serializer = new 
DataContractSerializer(typeof(LocationDetail)); 
                            serializer.WriteObject(fileStream, items); 
 
                        } 
                        NavigationService.Navigate(new Uri("/MapViewDetailsPage.xaml", UriKind.Relative)); 
                        break; 
                    } 
                } 
            } 
            catch 
            { 
            } 
        }

ScreenShots







And please read more about this at my MSDN Code sample

Author:SubramanyamRaju

Blog:http://bsubramanyamraju.blogspot.in/

See Also

Another important place to find a huge amount of Windows Phone related articles is the TechNet Wiki itself. The best entry point is Windows Phone Resources on the TechNet Wiki.