In latest XF version (4.5.0.617) using ObservableCollection.RemoveAt(index) with a valid index raises ArgementOutOfRangeException.
It is an iOS exception only. On Android that exact same code it is working fine.
The ObservableCollection is bound to the ItemsSourceof a CarouselViewand the ObservableCollection.RemoveAt(index) is executed in an event raised bij the Messenger-Service (not on the main thread). If the code is changed to:
var list = ObservableCollection.ToList();
list.RemoveAt(index)
ObservableCollection = new ObservableCollection(list)
The codes executes fine on iOS and without raising any Exception.
The index is valid. For example 5 in a collection count of 20.
@goedware Can you please attach a small project that demonstrates this issue? Thanks!
Attached a sample project.
Start the app, swipe to an item in the CarouselView, press Delete button. A Modal Page opens. Press Close button and a message is send to delete the current item in the CarouselView. On Android that item is removed by ObservableCollection.RemoveAt(index). On iOS the application crashes with an exception (ArgementOutOfRangeException) on that same line of code.
Hope this helps.
This is the stacktrace:
Unhandled Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x00009] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/List.cs:161
at System.Collections.ObjectModel.Collection`1[T].System.Collections.IList.get_Item (System.Int32 index) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/ObjectModel/Collection.cs:266
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.ElementAt (System.Int32 index) [0x0000f] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:268
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.get_Item (System.Int32 index) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:37
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.GetIndexForItem (System.Object item) [0x00004] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:71
at Xamarin.Forms.Platform.iOS.CarouselViewController.CollectionItemsSourceChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000c] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\CarouselViewController.cs:122
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.CollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x00055] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:132
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.CollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x0002d] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:105
at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00018] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:263
at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedAction action, System.Object item, System.Int32 index) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:338
at System.Collections.ObjectModel.ObservableCollection`1[T].RemoveItem (System.Int32 index) [0x00021] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:182
at System.Collections.ObjectModel.Collection`1[T].RemoveAt (System.Int32 index) [0x00027] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/ObjectModel/Collection.cs:144
at ObservableCollectionTest.MainPage.Callback (Xamarin.Forms.Page page) [0x0001d] in /Users/jsuarez/Downloads/ObservableCollectionTest/ObservableCollectionTest/ObservableCollectionTest/MainPage.xaml.cs:40
at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:395
--- End of inner exception stack trace ---
at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00081] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:409
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Reflection/MethodBase.cs:53
at Xamarin.Forms.MessagingCenter+Subscription.InvokeCallback (System.Object sender, System.Object args) [0x00064] in D:\a\1\s\Xamarin.Forms.Core\MessagingCenter.cs:94
at Xamarin.Forms.MessagingCenter.InnerSend (System.String message, System.Type senderType, System.Type argType, System.Object sender, System.Object args) [0x0006b] in D:\a\1\s\Xamarin.Forms.Core\MessagingCenter.cs:217
at Xamarin.Forms.MessagingCenter.Xamarin.Forms.IMessagingCenter.Send[TSender] (TSender sender, System.String message) [0x00013] in D:\a\1\s\Xamarin.Forms.Core\MessagingCenter.cs:127
at ObservableCollectionTest.ModalPage.OnCloseClicked (System.Object sender, System.EventArgs e) [0x0000d] in /Users/jsuarez/Downloads/ObservableCollectionTest/ObservableCollectionTest/ObservableCollectionTest/ModalPage.xaml.cs:19
at Xamarin.Forms.Button.Xamarin.Forms.Internals.IButtonElement.PropagateUpClicked () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Button.cs:185
at Xamarin.Forms.ButtonElement.ElementClicked (Xamarin.Forms.VisualElement visualElement, Xamarin.Forms.Internals.IButtonElement ButtonElementManager) [0x0001f] in D:\a\1\s\Xamarin.Forms.Core\ButtonElement.cs:61
at Xamarin.Forms.Button.SendClicked () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Button.cs:171
at Xamarin.Forms.Platform.iOS.ButtonElementManager.OnButtonTouchUpInside (Xamarin.Forms.IButtonController element) [0x00009] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ButtonElementManager.cs:86
at Xamarin.Forms.Platform.iOS.ButtonRenderer.OnButtonTouchUpInside (System.Object sender, System.EventArgs eventArgs) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ButtonRenderer.cs:147
at UIKit.UIControlEventProxy.Activated () [0x00004] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIControl.cs:38
--- End of stack trace from previous location where exception was thrown ---
at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at ObservableCollectionTest.iOS.Application.Main (System.String[] args) [0x00001] in /Users/jsuarez/Downloads/ObservableCollectionTest/ObservableCollectionTest/ObservableCollectionTest.iOS/Main.cs:17
2020-04-21 09:38:40.066339+0200 ObservableCollectionTest.iOS[5961:215658] Unhandled managed exception: Exception has been thrown by the target of an invocation. (System.Reflection.TargetInvocationException)
at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00081] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:409
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Reflection/MethodBase.cs:53
at Xamarin.Forms.MessagingCenter+Subscription.InvokeCallback (System.Object sender, System.Object args) [0x00064] in D:\a\1\s\Xamarin.Forms.Core\MessagingCenter.cs:94
at Xamarin.Forms.MessagingCenter.InnerSend (System.String message, System.Type senderType, System.Type argType, System.Object sender, System.Object args) [0x0006b] in D:\a\1\s\Xamarin.Forms.Core\MessagingCenter.cs:217
at Xamarin.Forms.MessagingCenter.Xamarin.Forms.IMessagingCenter.Send[TSender] (TSender sender, System.String message) [0x00013] in D:\a\1\s\Xamarin.Forms.Core\MessagingCenter.cs:127
at ObservableCollectionTest.ModalPage.OnCloseClicked (System.Object sender, System.EventArgs e) [0x0000d] in /Users/jsuarez/Downloads/ObservableCollectionTest/ObservableCollectionTest/ObservableCollectionTest/ModalPage.xaml.cs:19
at Xamarin.Forms.Button.Xamarin.Forms.Internals.IButtonElement.PropagateUpClicked () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Button.cs:185
at Xamarin.Forms.ButtonElement.ElementClicked (Xamarin.Forms.VisualElement visualElement, Xamarin.Forms.Internals.IButtonElement ButtonElementManager) [0x0001f] in D:\a\1\s\Xamarin.Forms.Core\ButtonElement.cs:61
at Xamarin.Forms.Button.SendClicked () [0x00000] in D:\a\1\s\Xamarin.Forms.Core\Button.cs:171
at Xamarin.Forms.Platform.iOS.ButtonElementManager.OnButtonTouchUpInside (Xamarin.Forms.IButtonController element) [0x00009] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ButtonElementManager.cs:86
at Xamarin.Forms.Platform.iOS.ButtonRenderer.OnButtonTouchUpInside (System.Object sender, System.EventArgs eventArgs) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ButtonRenderer.cs:147
at UIKit.UIControlEventProxy.Activated () [0x00004] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIControl.cs:38
--- End of stack trace from previous location where exception was thrown ---
at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at ObservableCollectionTest.iOS.Application.Main (System.String[] args) [0x00001] in /Users/jsuarez/Downloads/ObservableCollectionTest/ObservableCollectionTest/ObservableCollectionTest.iOS/Main.cs:17
--- inner exception ---
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index (System.ArgumentOutOfRangeException)
at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x00009] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/Generic/List.cs:161
at System.Collections.ObjectModel.Collection`1[T].System.Collections.IList.get_Item (System.Int32 index) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/ObjectModel/Collection.cs:266
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.ElementAt (System.Int32 index) [0x0000f] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:268
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.get_Item (System.Int32 index) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:37
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.GetIndexForItem (System.Object item) [0x00004] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:71
at Xamarin.Forms.Platform.iOS.CarouselViewController.CollectionItemsSourceChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000c] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\CarouselViewController.cs:122
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.CollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x00055] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:132
at Xamarin.Forms.Platform.iOS.ObservableItemsSource.CollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x0002d] in D:\a\1\s\Xamarin.Forms.Platform.iOS\CollectionView\ObservableItemsSource.cs:105
at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00018] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:263
at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedAction action, System.Object item, System.Int32 index) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:338
at System.Collections.ObjectModel.ObservableCollection`1[T].RemoveItem (System.Int32 index) [0x00021] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.ObjectModel/src/System/Collections/ObjectModel/ObservableCollection.cs:182
at System.Collections.ObjectModel.Collection`1[T].RemoveAt (System.Int32 index) [0x00027] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/Common/src/CoreLib/System/Collections/ObjectModel/Collection.cs:144
at ObservableCollectionTest.MainPage.Callback (Xamarin.Forms.Page page) [0x0001d] in /Users/jsuarez/Downloads/ObservableCollectionTest/ObservableCollectionTest/ObservableCollectionTest/MainPage.xaml.cs:40
at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection/RuntimeMethodInfo.cs:395
Similar issues have been reported a few times now over the last 5 months without resolution. CollectionViews, and by the looks of this issue - CarouselViews, simply don't support offscreen ObservableCollection changes (add or delete). It was broken in December and I haven't seen any urgency in trying to fix it. I pity the poor developer potentially tasked with updating the VS template for a XF Shell based app to use the latest and greatest CollectionView instead of the old ListView.
Hi everyone can you try this package, I think it's fixed on next 4.6
I was looking at the sample, are you Subscribing twice to the Message, since when the Modal is disposed the appearing of the MainPage is called again*
Hi everyone can you try this package, I think it's fixed on next 4.6
Xamarin.Forms.4.6.0.691.nupkg.zip
Well done! It looks like you fixed the ObservableCollection issues. That package supports offscreen additions and deletions and doesn't appear to leave behind empty rows etc. Now if you could just fix the iOS grid layout and horizontal item spacing bugs I might finally be able to get a CollectionView into production. ;-)
I was looking at the sample, are you Subscribing twice to the Message, since when the Modal is disposed the appearing of the MainPage is called again*
Yes, in the sample it is, quick sample project 馃懠...
But in the real life case the message is only subscribed once.
Most helpful comment
Similar issues have been reported a few times now over the last 5 months without resolution. CollectionViews, and by the looks of this issue - CarouselViews, simply don't support offscreen ObservableCollection changes (add or delete). It was broken in December and I haven't seen any urgency in trying to fix it. I pity the poor developer potentially tasked with updating the VS template for a XF Shell based app to use the latest and greatest CollectionView instead of the old ListView.