I'm trying to set up a simple Bing Map web part that would pull list items to populate the map with pins. I was able to get a static data pull (created objects to populate pins), but once I tacked in the Client OM code, it stopped working. It didn't fail, but it didn't work and I couldn't connect the debugger.
I'm completely stumped as to what's going wrong. Here are my questions:
- Why can I not get the debugger to recognize my breakpoints when connected to all the iexplorer.exe instances?
- Why does my code not run? I don't see the dll deployed anywhere, so should that be deployed and to where?
- Is there a way to automatically have the SharePoint project deploy to clientbin? The only way I've found to get this to work is by manually dragging the xap into the mapped clientbin folder in the SP project.
- List item
Here's my XAML markup:
<UserControl x:Class="FH.SharePoint.Offices.POIMap.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:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<m:Map CredentialsProvider="APIKey" x:Name="NearbyPOIMap" Mode="Road">
<m:MapLayer Name="uxErrorLayer" Visibility="Collapsed">
<Canvas m:MapLayer.Position="0,0" Background="Blue" Width="340" Height="30">
<TextBlock FontWeight="Bold" Foreground="Red" Text="Error retreiving offices locations from the server" TextWrapping="Wrap" Margin="5" MaxWidth="100" MaxHeight="40"></TextBlock>
</Canvas>
</m:MapLayer>
</m:Map>
</Grid>
Here's the code I have. I commented out the section that worked in the test VS Web App I created. Even that didn't work once I deployed to SharePoint.
public struct NearbyPOI
{
public string NearbyName;
public string NearbyAddress1;
public string NearbyAddress2;
public string NearbyCity;
public string NearbyState;
public string NearbyZip;
public string NearbyCountry;
public string NearbyEntityType;
public double NearbyLatitude;
public double NearbyLongitude;
public Location GetLocation()
{
return new Location(this.NearbyLatitude, this.NearbyLongitude);
}
public static string GetFormattedTextForOffice(NearbyPOI poi)
{
StringBuilder sb = new StringBuilder(string.Empty);
string cszLine = "";
if (!string.IsNullOrEmpty(poi.NearbyName))
sb.AppendLine(poi.NearbyName);
if (!string.IsNullOrEmpty(poi.NearbyAddress1))
sb.AppendLine(poi.NearbyAddress1);
if (!string.IsNullOrEmpty(poi.NearbyAddress2))
sb.AppendLine(poi.NearbyAddress2);
if (!string.IsNullOrEmpty(poi.NearbyCity))
cszLine += poi.NearbyCity + " ";
if (!string.IsNullOrEmpty(poi.NearbyState))
cszLine += poi.NearbyState + " ";
if (!string.IsNullOrEmpty(poi.NearbyZip))
cszLine += poi.NearbyZip;
if (!String.IsNullOrEmpty(cszLine.Trim()))
sb.AppendLine(cszLine);
if (!string.IsNullOrEmpty(poi.NearbyCountry))
sb.AppendLine(poi.NearbyCountry);
return sb.ToString();
}
}
public partial class MainPage : UserControl
{
ClientContext clientContext;
ListItemCollection items;
List<NearbyPOI> nearbyPOI;
public MainPage()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
//Create a simple CamlQuery to return all items in the list
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = @"<View>
<Query>
<Where>
<IsNotNull>
<FieldRef Name='Title'/>
</IsNotNull>
</Where>
</Query>
<ViewFields>
<FieldRef Name='Title'/>
<FieldRef Name='NearbyCity'/>
<FieldRef Name='NearbyLatitude'/>
<FieldRef Name='NearbyLongitude'/>
<FieldRef Name='NearbyAddress1'/>
<FieldRef Name='NearbyAddress2'/>
<FieldRef Name='NearbyState'/>
<FieldRef Name='NearbyZip'/>
<FieldRef Name='NearbyCountry'/>
<FieldRef Name='NearbyEntityType'/>
</ViewFields>
</View>";
//We only want items from the currently selected list
List externalList = clientContext.Web.Lists.GetByTitle("Nearby POI"); //clientContext.Site.RootWeb.Lists.GetByTitle(ListName);
items = externalList.GetItems(camlQuery);
//Tell the ClientContext we want an instance of the list and the listitems
//determined by our CamlQuery earlier
//Note: This is not actually performing the calls to the server! This will occur
//when we call ExecuteQueryAsync()
clientContext.Load(externalList);
clientContext.Load(items);
//Perform the batched calls defined earlier
clientContext.ExecuteQueryAsync(PopulateListItemData, AsyncError);
//****This worked in the VS WebApp Project - Commented for SharePoint testing, didn't work in SP testing****
//NearbyPOI poi1 = BuildPoint("Home", "5 Rendina Ct.", "Ellisville", "MO", "63011", "USA", "Other", 38.600689, -90.592224);
//NearbyPOI poi2 = BuildPoint("McDonald's", "15924 Manchester Rd", "Ellisville", "MO", "63011", "USA", "Dining", 38.592258, -90.587532);
//NearbyPOI poi3 = BuildPoint("Drury Plaza", "355 Chesterfield Ctr.", "Chesterfield", "MO", "63017", "USA", "Lodging", 38.6524504423141, -90.5625142157078);
//AddPushPin(NearbyPOIMap, poi1);
//AddPushPin(NearbyPOIMap, poi2);
//AddPushPin(NearbyPOIMap, poi3);
}
//private static NearbyPOI BuildPoint(string name, string address1, string city, string state, string zip, string country, string type, double lat, double lng)
//{
// NearbyPOI poi = new NearbyPOI();
// poi.NearbyName = name;
// poi.NearbyAddress1 = address1;
// poi.NearbyCity = city;
// poi.NearbyState = state;
// poi.NearbyZip = zip;
// poi.NearbyCountry = country;
// poi.NearbyEntityType = type;
// poi.NearbyLatitude = lat;
// poi.NearbyLongitude = lng;
// return poi;
//}
private void PopulateListItemData(Object sender, ClientRequestSucceededEventArgs args)
{
nearbyPOI = new List<NearbyPOI>();
foreach (ListItem item in items)
{
NearbyPOI poi = new NearbyPOI();
double latitude = 0.0, longitude = 0.0;
poi.NearbyName = item["Title"].ToString();
poi.NearbyAddress1 = item["NearbyAddress1"].ToString();
poi.NearbyAddress2 = item["NearbyAddress2"].ToString();
poi.NearbyCity = item["NearbyCity"].ToString();
poi.NearbyState = item["NearbyState"].ToString();
poi.NearbyZip = item["NearbyZip"].ToString();
poi.NearbyCountry = item["NearbyCountry"].ToString();
poi.NearbyEntityType = item["NearbyEntityType"].ToString();
if (double.TryParse(item["NearbyLatitude"].ToString(), out latitude))
poi.NearbyLatitude = latitude;
if (double.TryParse(item["NearbyLongitude"].ToString(), out longitude))
poi.NearbyLongitude = longitude;
nearbyPOI.Add(poi);
}
Dispatcher.BeginInvoke(() =>
{
foreach (NearbyPOI poi in nearbyPOI)
{
AddPushPin(NearbyPOIMap, poi);
}
});
}
/// <summary>
/// checks if a pin already exists at the same location and if it does it just updates the tooltip otherwise it
/// adds the pushpin
/// </summary>
/// <param name="map"></param>
/// <param name="newPin"></param>
private void AddPushPin(Map map, NearbyPOI poi)
{
bool result = false;
foreach (UIElement element in map.Children)
{
if (element is Pushpin)
{
if (((Pushpin)element).Location == poi.GetLocation())
{
result = true;
Pushpin oldPin = element as Pushpin;
oldPin.myOffices.Add(poi);
ToolTip customTooltip = new ToolTip();
oldPin.Location = poi.GetLocation();
customTooltip.DataContext = oldPin;
customTooltip.Style = Application.Current.Resources["FHOfficeTooltipStyle"] as Style;
ToolTipService.SetToolTip(oldPin, customTooltip);
break;
}
}
}
if (!result)
{
Pushpin newPin = new Pushpin();
ToolTip customTooltip = new ToolTip();
newPin.myOffices.Add(poi);
newPin.Location = poi.GetLocation();
customTooltip.DataContext = newPin;
customTooltip.Style = Application.Current.Resources["FHOfficeTooltipStyle"] as Style;
ToolTipService.SetToolTip(newPin, customTooltip);
map.Children.Add(newPin);
}
}
private void AsyncError(Object sender, ClientRequestFailedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
this.uxErrorLayer.Visibility = Visibility.Visible;
});
}
}
public partial class Pushpin : Microsoft.Maps.MapControl.Pushpin
{
public List<NearbyPOI> myOffices = new List<NearbyPOI>();
public string GetFormattedPushpinTooltip
{
get
{
StringBuilder sb = new StringBuilder(string.Empty);
foreach (NearbyPOI office in this.myOffices)
{
sb.AppendLine(NearbyPOI.GetFormattedTextForOffice(office));
}
return sb.ToString();
}
}
}