Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8148489
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T14:39:22+00:00 2026-06-06T14:39:22+00:00

I’m working on this surface project where we have a bing maps control and

  • 0

I’m working on this surface project where we have a bing maps control and where we would like to draw polylines on the map, by using databinding.

The strange behaviour that’s occuring is that when I click the Add button, nothing happens on the map. If I move the map little bit, the polyline is drawn on the map. Another scenario that kind of works, is click the add button once, nothing happens, click it again both polylines are drawn. (In my manual collection I have 4 LocationCollections) so the same happens for the 3rd click and the fourth click where again both lines are drawn.

I have totally no idea where to look anymore to fix this. I have tried subscribing to the Layoutupdated events, which occur in both cases. Also added a collectionchanged event to the observablecollection to see if the add is triggered, and yes it is triggered. Another thing I tried is changing the polyline to pushpin and take the first location from the collection of locations in the pipelineviewmodel, than it’s working a expected.

I have uploaded a sample project for if you want to see yourself what’s happening.

Really hope that someone can point me in the right direction, because i don’t have a clue anymore.

Below you find the code that i have written:

I have the following viewmodels:

MainViewModel

public class MainViewModel
{
    private ObservableCollection<PipelineViewModel> _pipelines;

    public ObservableCollection<PipelineViewModel> Pipes
    {
        get { return _pipelines; }
    }

    public MainViewModel()
    {
        _pipelines = new ObservableCollection<PipelineViewModel>();
    }
}

And the PipelineViewModel which has the collection of Locations which implements INotifyPropertyChanged:

PipelineViewModel

public class PipelineViewModel : ViewModelBase
{
    private LocationCollection _locations;

    public string Geometry { get; set; }
    public string Label { get; set; }
    public LocationCollection Locations
    {
        get { return _locations; }
        set
        {
            _locations = value;
            RaisePropertyChanged("Locations");
        }
    }
}

My XAML looks like below:

<s:SurfaceWindow x:Class="SurfaceApplication3.SurfaceWindow1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="http://schemas.microsoft.com/surface/2008"
    xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF" 
    Title="SurfaceApplication3">
    <s:SurfaceWindow.Resources>
        <DataTemplate x:Key="Poly">
            <m:MapPolyline Locations="{Binding Locations}" Stroke="Black" StrokeThickness="5" />
        </DataTemplate>
    </s:SurfaceWindow.Resources>
  <Grid>
        <m:Map ZoomLevel="8" Center="52.332074,5.542302" Name="Map">
            <m:MapItemsControl Name="x" ItemsSource="{Binding Pipes}" ItemTemplate="{StaticResource Poly}" />
        </m:Map>
        <Button Name="add" Width="100" Height="50" Content="Add" Click="add_Click"></Button>
    </Grid>
</s:SurfaceWindow>

And in our codebehind we are setting up the binding and the click event like this:

private int _counter = 0;
private string[] geoLines;

private MainViewModel _mainViewModel = new MainViewModel();

/// <summary>
/// Default constructor.
/// </summary>
public SurfaceWindow1()
{
    InitializeComponent();

    // Add handlers for window availability events
    AddWindowAvailabilityHandlers();

    this.DataContext = _mainViewModel;

    geoLines = new string[4]{ "52.588032,5.979309; 52.491143,6.020508; 52.397391,5.929871; 52.269838,5.957336; 52.224435,5.696411; 52.071065,5.740356",
                                "52.539614,4.902649; 52.429222,4.801025; 52.308479,4.86145; 52.246301,4.669189; 52.217704,4.836731; 52.313516,5.048218",
                                "51.840869,4.394531; 51.8731,4.866943; 51.99841,5.122375; 52.178985,5.438232; 51.8731,5.701904; 52.071065,6.421509",
                                "51.633362,4.111633; 51.923943,6.193542; 52.561325,5.28717; 52.561325,6.25946; 51.524125,5.427246; 51.937492,5.28717" };
}

private void add_Click(object sender, RoutedEventArgs e)
{
    PipelineViewModel plv = new PipelineViewModel();
    plv.Locations = AddLinestring(geoLines[_counter]);
    plv.Geometry = geoLines[_counter];

    _mainViewModel.Pipes.Add(plv);

    _counter++;
}

private LocationCollection AddLinestring(string shapegeo)
{
    LocationCollection shapeCollection = new LocationCollection();

    string[] lines = Regex.Split(shapegeo, ";");
    foreach (string line in lines)
    {
        string[] pts = Regex.Split(line, ",");

        double lon = double.Parse(pts[1], new CultureInfo("en-GB"));
        double lat = double.Parse(pts[0], new CultureInfo("en-GB"));
        shapeCollection.Add(new Location(lat, lon));
    }

    return shapeCollection;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T14:39:23+00:00Added an answer on June 6, 2026 at 2:39 pm

    I did some digging on this problem and found that there is a bug in the Map implementation. I also made a workaround for it which can be used like this

    <m:Map ...>
        <m:MapItemsControl Name="x"
                           behaviors:MapFixBehavior.FixUpdate="True"/>
    </m:Map>
    

    I included this fix in your sample application and uploaded it here: SurfaceApplication3.zip


    The visual tree for each ContentPresenter looks like this

    enter image description here

    When you add a new item to the collection the Polygon gets the wrong Points initially. Instead of values like 59, 29 it gets something like 0.0009, 0.00044.

    The points are calculated in MeasureOverride in MapShapeBase and the part that does the calculation looks like this

    MapMath.TryLocationToViewportPoint(ref this._NormalizedMercatorToViewport, location, out point2);
    

    Initially, _NormalizedMercatorToViewport will have its default values (everything is set to 0) so the calculations goes all wrong. _NormalizedMercatorToViewport gets set in the method SetView which is called from MeasureOverride in MapLayer.

    MeasureOverride in MapLayer has the following two if statements.

    if ((element is ContentPresenter) && (VisualTreeHelper.GetChildrenCount(element) > 0))
    {
        child.SetView(...)
    }
    

    This comes out as false because the ContentPresenter hasn’t got a visual child yet, it is still being generated. This is the problem.

    The second one looks like this

    IProjectable projectable2 = element as IProjectable;
    if (projectable2 != null)
    {
        projectable2.SetView(...);
    }
    

    This comes out as false as well because the element, which is a ContentPresenter, doesn’t implement IProjectable. This is implemented by the child MapShapeBase and once again, this child hasn’t been generated yet.

    So, SetView never gets called and _NormalizedMercatorToViewport in MapShapeBase will have its default values and the calculations goes wrong the first time when you add a new item.


    Workaround

    To workaround this problem we need to force a re-measure of the MapLayer. This has to be done when a new ContentPresenter is added to the MapItemsControl but after the ContentPresenter has a visual child.

    One way to force an update is to create an attached property which has the metadata-flags AffectsRender, AffectsArrange and AffectsMeasure set to true. Then we just change the value of this property everytime we want to do the update.

    Here is an attached behavior which does this. Use it like this

    <m:Map ...>
        <m:MapItemsControl Name="x"
                           behaviors:MapFixBehavior.FixUpdate="True"/>
    </m:Map>
    

    MapFixBehavior

    public class MapFixBehavior
    {
        public static DependencyProperty FixUpdateProperty =
            DependencyProperty.RegisterAttached("FixUpdate",
                                                typeof(bool),
                                                typeof(MapFixBehavior),
                                                new FrameworkPropertyMetadata(false,
                                                                              OnFixUpdateChanged));
    
        public static bool GetFixUpdate(DependencyObject mapItemsControl)
        {
            return (bool)mapItemsControl.GetValue(FixUpdateProperty);
        }
        public static void SetFixUpdate(DependencyObject mapItemsControl, bool value)
        {
            mapItemsControl.SetValue(FixUpdateProperty, value);
        }
    
        private static void OnFixUpdateChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
        {
            MapItemsControl mapItemsControl = target as MapItemsControl;
            ItemsChangedEventHandler itemsChangedEventHandler = null;
            itemsChangedEventHandler = (object sender, ItemsChangedEventArgs ea) =>
            {
                if (ea.Action == NotifyCollectionChangedAction.Add)
                {
                    EventHandler statusChanged = null;
                    statusChanged = new EventHandler(delegate
                    {
                        if (mapItemsControl.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
                        {
                            mapItemsControl.ItemContainerGenerator.StatusChanged -= statusChanged;
                            int index = ea.Position.Index + ea.Position.Offset;
                            ContentPresenter contentPresenter =
                                mapItemsControl.ItemContainerGenerator.ContainerFromIndex(index) as ContentPresenter;
                            if (VisualTreeHelper.GetChildrenCount(contentPresenter) == 1)
                            {
                                MapLayer mapLayer = GetVisualParent<MapLayer>(mapItemsControl);
                                mapLayer.ForceMeasure();
                            }
                            else
                            {
                                EventHandler layoutUpdated = null;
                                layoutUpdated = new EventHandler(delegate
                                {
                                    if (VisualTreeHelper.GetChildrenCount(contentPresenter) == 1)
                                    {
                                        contentPresenter.LayoutUpdated -= layoutUpdated;
                                        MapLayer mapLayer = GetVisualParent<MapLayer>(mapItemsControl);
                                        mapLayer.ForceMeasure();
                                    }
                                });
                                contentPresenter.LayoutUpdated += layoutUpdated;
                            }
                        }
                    });
                    mapItemsControl.ItemContainerGenerator.StatusChanged += statusChanged;
                }
            };
            mapItemsControl.ItemContainerGenerator.ItemsChanged += itemsChangedEventHandler;
        }
    
        private static T GetVisualParent<T>(object childObject) where T : Visual
        {
            DependencyObject child = childObject as DependencyObject;
            while ((child != null) && !(child is T))
            {
                child = VisualTreeHelper.GetParent(child);
            }
            return child as T;
        }
    }
    

    MapLayerExtensions

    public static class MapLayerExtensions
    {
        private static DependencyProperty ForceMeasureProperty =
            DependencyProperty.RegisterAttached("ForceMeasure",
                                                typeof(int),
                                                typeof(MapLayerExtensions),
                                                new FrameworkPropertyMetadata(0,
                                                    FrameworkPropertyMetadataOptions.AffectsRender |
                                                    FrameworkPropertyMetadataOptions.AffectsArrange |
                                                    FrameworkPropertyMetadataOptions.AffectsMeasure));
    
        private static int GetForceMeasure(DependencyObject mapLayer)
        {
            return (int)mapLayer.GetValue(ForceMeasureProperty);
        }
        private static void SetForceMeasure(DependencyObject mapLayer, int value)
        {
            mapLayer.SetValue(ForceMeasureProperty, value);
        }
    
        public static void ForceMeasure(this MapLayer mapLayer)
        {
            SetForceMeasure(mapLayer, GetForceMeasure(mapLayer) + 1);
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I have some data like this: 1 2 3 4 5 9 2 6
I would like to count the length of a string with PHP. The string
For some reason, after submitting a string like this Jack’s Spindle from a text
this is what i have right now Drawing an RSS feed into the php,
I have this code to decode numeric html entities to the UTF8 equivalent character.
I would like to run a str_replace or preg_replace which looks for certain words
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have thousands of HTML files to process using Groovy/Java and I need to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.