How to resolve Xamarin Forms System.ArgumentException: 'An item with the same key has already been added. Key: Xamarin.Forms.BindableProperty'

Viewed 658

When adding over 100 map pins to Xamarin.Forms.GoogleMap using a custom pin template I get the following error randomly "System.ArgumentException: 'An item with the same key has already been added. Key: Xamarin.Forms.BindableProperty'" setting a brake point on the exception it takes me to the generated class for the Pin template. Looking for pointers to figure out what is causing this. I get a 3 to a ~50ish pins to load before the error is thrown.

Generated Class Throwing the error:

[global::Xamarin.Forms.Xaml.XamlFilePathAttribute("ViewModels\\MapPinTemplate.xaml")]
public partial class MapPinTemplate : global::Xamarin.Forms.StackLayout {

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Forms.Build.Tasks.XamlG", "2.0.0.0")]
    private void InitializeComponent() {
        global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(MapPinTemplate));
    }
}

MapPinTemplate Class:

public partial class MapPinTemplate : StackLayout
{
    public MapPinTemplate(string name, string resourceStatusColor)
    {
        InitializeComponent();
        //crash.SetPage(this.GetType().Name);
        try
        {
            Display = name ?? "ERROR";
            ResourceStatusColor = Color.FromHex(resourceStatusColor ?? "#4f5467");
        }
        catch
        {

        }
        BindingContext = this;
    }

    public Color ResourceStatusColor { get; private set; }
    public string Display { get; private set; }

    public void SetName(string name)
    {
        if (!String.IsNullOrWhiteSpace(name))
        {
            Display = name;
        }
    }

    public void SetResourceStatusColor(string color)
    {
        if (!String.IsNullOrWhiteSpace(color))
        {
            ResourceStatusColor = Color.FromHex(color);
        }
    }
}

Map Pin Template xaml:

<StackLayout
         WidthRequest="60" 
         HeightRequest="22"
         AnchorX="0.1"
         AnchorY="0.5"
         xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Project.MapPinTemplate">
<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
    <Label Text="{Binding Display }" BackgroundColor="{Binding ResourceStatusColor}" TextColor="White" FontSize="Medium" HorizontalTextAlignment="Center" 
            AbsoluteLayout.LayoutBounds=".1, .5, 60, 22"
            AbsoluteLayout.LayoutFlags="None" />
</AbsoluteLayout>

Code Loading the Map Pins:

    public async void LoadPins()
    {
        try
        {
            //TODO: Secure Endpoint
            HttpClientHelper httpClientHelper = new HttpClientHelper(appHelper.BaseUrl + "GetPins/");
            var Items = await httpClientHelper.LoadDataTable<Locations>(false);
                 Parallel.ForEach(Items, (a) =>
                {
                    try
                    {
                        if (a.Lat != 0 & a.Lng != 0)
                        {

                            if (!String.IsNullOrWhiteSpace(a.PinType) && !String.IsNullOrWhiteSpace(a.IconName))
                            {
                                var apl = new LocationPin();
                                bool success = true;
                                apl.Hydrant = a;
                                apl.Pin = new Pin();
                                apl.Pin.Address = a.Address ?? "";
                                apl.Pin.IsDraggable = false;
                                apl.Pin.Position = new Position(a.Lat, a.Lng);
                                apl.Pin.Type = PinType.Generic;
                                apl.Pin.Label = a.PinType;
                                apl.Pin.Tag = a.PinId;
                                try
                                {

                                    apl.PinTemplate = new PinTemplate(a.PinType, a.IconName, 45, 45);
                                    var icon = BitmapDescriptorFactory.FromView(apl.PinTemplate);
                                    apl.Pin.Icon = icon;
                                }
                                catch (NullReferenceException ex)
                                {
                                    success = false;
                                }
                                catch (System.ArgumentException ex)
                                {
                                    //Exception is not caught here
                                    success = false;
                                }
                                apl.Pin.IsVisible = PinsEnabled;
                                apl.Pin.Clicked += Pin_Clicked;
                                try
                                {

                                    if (hlps != null && apl != null && success == true)
                                    {                                            
                                        hlps.Add(apl);
                                    }
                                }
                                catch
                                {

                                }
                            }
                        }
                    }
                    catch
                    {

                    }
                });
            foreach(var a in hlps.Where(h => h.Pin != null))
            {
                try
                {
                    await Device.InvokeOnMainThreadAsync(() =>
                    {
                        map.Pins.Add(a.Pin);
                    });
                    await Task.Delay(70);
                }
                catch(Exception ex) { }
            }
        }
        catch (Exception ex)
        {
            if (Pins != 5)
            {
                Pins++;
                LoadPins();
            }
            else
            {

                var dialog = new SimpleDialog(SimpleDialog.MessageType.Error, "Error", "There was an error loading pins.", "OK");
               await PopupNavigation.Instance.PushAsync(dialog);

            }
        }
    }
0 Answers
Related