On a recent Silverlight project, I was integrating the Bing Maps Control into an application that was using the M-V-VM pattern. I came across this introduction that helped spark my imagination: http://www.jamesrichards.com/post/2009/09/28/Implementing-Model-View-ViewModel-with-the-Bing-Maps-(Virtual-Earth)-Silverlight-Map-Control.aspx
While I was adding various shapes to the map control, I ran into an issue when trying to bind to the Stroke property of the MapPolygon or MapPolyline controls as shown in the code below:
|
<UserControl x:Class="BingMaps.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"
xmlns:vm="clr-namespace:BingMaps.ViewModels"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
>
<UserControl.DataContext>
<vm:MainViewModel />
</UserControl.DataContext>
<Grid x:Name="LayoutRoot">
<bing:Map CredentialsProvider="****">
<bing:MapPolygon Stroke="{Binding StrokeColor}"
StrokeThickness="5"
Locations="0,0 0,50 50,50 50,0" />
</bing:Map>
</Grid>
</UserControl>
|
I kept getting the dreaded XamlParseException: AG_E_PARSER_BAD_PROPERTY_VALUE error! I tried with the StrokeColor as well as the StrokeBrush properties found in my MainViewModel class, to no avail.
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
StrokeColor = "#FF000000";
StrokeBrush = new SolidColorBrush(Colors.Black);
}
private string strokeColor;
public string StrokeColor
{
get { return strokeColor; }
set
{
if ( strokeColor != value )
{
strokeColor = value;
RaisePropertyChanged("StrokeColor");
}
}
}
private Brush strokeBrush;
public Brush StrokeBrush
{
get
{
return strokeBrush;
}
set
{
if ( strokeBrush != value )
{
strokeBrush = value;
RaisePropertyChanged("StrokeBrush");
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if ( PropertyChanged != null )
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
So I came up with the following work around, which I know is not pure M-V-VM, but I could not figure out why the previous attempts were not working.
|
<bing:MapPolygon Loaded="MapPolygon_Loaded"
StrokeThickness="5"
Locations="0,0 0,50 50,50 50,0" />
|
and in the code behind...
private void MapPolygon_Loaded(object sender, RoutedEventArgs e)
{
var polygon = sender as MapPolygon;
var model = polygon.DataContext as MainViewModel;
polygon.Stroke = model.StrokeBrush;
}
Now, running the application gives us the following result. If anyone knows the cause of this problem, please let me know, otherwise, I hope this work around saves someone else the time it took me trying to resolve it.
Hope that helps!
Bobby