简体   繁体   中英

How can I iterate over a Xamarin.Forms.Maps Map.Pins list while modifying the list?

I'm working on a Xamarin.Forms app the utilizes the Maps package. The Map object contains an IList Pins which stores the list of Pin objects that contain Label, Position and other properties. I am attempting to update this Pins list by comparing their Position to a Collection of custom objects that contain the same properties (ID, Position, etc) as well as whether or not they exist on this list anymore, and removing them accordingly.

To elaborate, with every update, I want to iterate through the Pins list, remove any pins that no longer correspond to an object in the collection, add any pins that correspond to new objects in the collection, and change the positions of any pins where the positions of the corresponding object has changed.

I am attempting to do this by iterating over the Pins and comparing accordingly while removing, adding and altering the Pins when necessary. The problem here is that I get the following error each time a Pin is removed:

An exception of type 'System.InvalidOperationException' occurred in mscorlib.dll but was not handled in user code
Collection was modified; enumeration operation may not execute.

This is to be expected when modifying a list that is being iterated over, however all of the solutions available to work around this, such as using Maps.Pins.ToList() when instantiating the foreach loop, using a for loop instead of a foreach loop, or even creating a copy of the Pins list to iterate over while modifying the original, don't solve this problem.

I know some of these solutions work because I've used them to overcome this problem when comparing lists of my custom objects, but for some reason, none of them seem to work with the Map.Pins list. Can anyone point out what I may be doing wrong, or if there is some detail about Map.Pins list that excludes it from these solutions? Is there another way to solve this problem?

For reference here are the ways, in code, I have tried to implement the "remove pins that should no longer exist" functionality:

.ToList()

foreach (Pin pin in map.Pins.ToList())
            {
                if (!newList.Any(x => x.ID == pin.Label))
                {
                    Debug.WriteLine("Pin " + pin.Label + " is being removed.");
                    map.Pins.Remove(pin);
                }
            }

For Loop

            for (int i = 0; i < map.Pins.Count; i++) {
                Debug.WriteLine(map.Pins[i].Label);
                if (!newList.Any(x => x.ID == map.Pins[i].Label))
                {
                    Debug.WriteLine("Pin " + map.Pins[i].Label + " is being removed.");
                    map.Pins.Remove(map.Pins[i]);
                }
            }

Creation of new list

List<Pin> oldPins = new List<Pin>();

            foreach (Pin pin in map.Pins)
            {
                oldPins.Add(pin);
            }

foreach (Pin pin in oldPins)
            {
                if (!newList.Any(x => x.ID == pin.Label))
                {
                    Debug.WriteLine("Pin " + pin.Label + " is being removed.");
                    map.Pins.Remove(pin);
                }
            }

// I tried this with the for loop solution as well

Thanks very much in advance

For the for loop method to work, you need to count backwards, otherwise your index will be thrown off each time you remove an item.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM