Geeks With Blogs
bobby's blog randomly specific...

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

Posted on Saturday, February 27, 2010 12:45 AM Silverlight , MVVM , Bing Maps | Back to top


Comments on this post: Bing Maps Data Binding Issues - Can't Bind to Stroke Property

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
I see you're binding to the StrokeColor property in Xaml, but setting the StrokeBrush through code (which is correct / Stroke is of Brush type). Tried binding to StrokeBrush in Xaml as well?
Left by Andrej Tozon | @andrejt on Mar 07, 2010 4:50 AM

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
Andrej -

I did try binding to both properties and got an error each time. Have you been able to find a way that works?
Left by Bobby Diaz on Mar 08, 2010 5:21 PM

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
Hi Bobby,

I'm glad my post sparked your imagination! I really like the approach you've taken in your Earthquake application. Especially all the binding that's happening on the Map and MapItemsControl. Nicely done.

Have you tried anything similar with the ESRI Silverlight Map control? I was thinking of porting your example to see how well that control plays with your binding concepts. I'm curious if you've already explored that?

Cheers!

James
Left by James Richards on Mar 14, 2010 12:29 AM

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
@James, thanks for checking out the demo!

I have not looked into the ESRI Map Control. I have been using the Bing Maps control on several recent projects and the Earthquake Locator is a safe way for me to share what I have learned.

Thanks,
Bobby
Left by Bobby Diaz on Mar 14, 2010 3:39 AM

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
Hi, did you ever get binding to work with the MapPolygon class? I am trying to bind StrokeThickness. Looks like that the StrokeThickness Property does not have a Dependency Property, and I am thinking this is the reason it does not work.
Left by zeroone on Jul 04, 2010 7:12 PM

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
Check out my code. The "StrokeForeColor" comes from my view model. It's a string containing the hex color value, originally save in my database.

True MVVM. :-)

XAML:

<local:MapBorder BorderColor="{Binding StrokeForeColor}" />

Code:

public class MapBorder : MapPolyline
{

public String BorderColor
{
get { return (String)GetValue(BorderColorProperty); }
set { SetValue(BorderColorProperty, value); }
}

public static readonly DependencyProperty BorderColorProperty =
DependencyProperty.Register("BorderColor", typeof(string), typeof(MapBorder), new PropertyMetadata(null, ChangeBackground));

private static void ChangeBackground(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MapBorder).Stroke = HexColor(e.NewValue as string);
}

private static SolidColorBrush HexColor(String hex)
{
//remove the # at the front
hex = hex.Replace("#", "");
byte a = 255;
byte r = 255;
byte g = 255;
byte b = 255;
int start = 0;

//handle ARGB strings (8 characters long)
if (hex.Length == 8)
{
a = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
start = 2;
}
//convert RGB characters to bytes
r = byte.Parse(hex.Substring(start, 2), System.Globalization.NumberStyles.HexNumber);
g = byte.Parse(hex.Substring(start + 2, 2), System.Globalization.NumberStyles.HexNumber);
b = byte.Parse(hex.Substring(start + 4, 2), System.Globalization.NumberStyles.HexNumber);

return new SolidColorBrush(Color.FromArgb(a, r, g, b));

}


}
Left by Ryan Shelby on Jul 09, 2010 11:01 PM

# re: Bing Maps Data Binding Issues - Can't Bind to Stroke Property
Requesting Gravatar...
Do you have the rest of the source code for this example? I am having trouble binding the map in the ViewModel.
Left by Patrick Riley on Oct 03, 2010 8:58 PM

Your comment:
 (will show your gravatar)


Copyright © Bobby Diaz | Powered by: GeeksWithBlogs.net