Forum Xamarin Cross Platform with Xamarin

Listview with grouping :System.ArgumentOutOfRangeException: Index was out of range

Hello,
I'm starting with xamarin and i'm facing a problem using the listview with grouping.
Here is my contentPage:

        RootMenuViewModel rootUserProfileViewModel;
        public RootMenuPage(RootPage rootPage)
        {            
            BindingContext = rootUserProfileViewModel = new RootMenuViewModel(this);          
            LoadUI();                        
        }
       private void LoadUI()
        {
            Title = "menu";
            listView = new ListView
            {
                HasUnevenRows=true,
                BindingContext = rootUserProfileViewModel,
                IsGroupingEnabled= true,
                GroupDisplayBinding = new Binding("GroupName"),                
                ItemTemplate = new DataTemplate(() => {                   
                    TextCell c = new TextCell();
                    c.SetBinding(TextCell.TextProperty, "Label");
                    return c;
                }),               
            };
            listView.SetBinding(ListView.ItemsSourceProperty, "GroupedClassif");

            //etc....
          }
          protected override async void OnAppearing()
        {
            base.OnAppearing();
             await rootUserProfileViewModel.LoadDataAsync();            
        }

My viewModel:

 class RootMenuViewModel : BaseViewModel
    {
        readonly IAuthService authService;
        readonly IDictionaryService dicoService;

        public ObservableCollection<ItemClassification> Classif { get; set; }
        public ObservableCollection<GroupItems> GroupedClassif { get; set; }

     public RootMenuViewModel(Page page)
            : base(page)
        {
            this.authService = DependencyService.Get<IAuthService>();
            this.dicoService = DependencyService.Get<IDictionaryService>();

            Classif = new ObservableCollection<ItemClassification>();
            GroupedClassif = new ObservableCollection<GroupItems>();
         }


         public async Task LoadDataAsync()
        {
            await Task.Run( () =>
            {               
              //here i create groups (GroupedClassif ): GroupedClassif.Add(group);
            });
    }

       public class GroupItems : ObservableCollection<ItemClassification>
       {
            public string GroupName { get;set; }
            public GroupItems(string groupName)
            {
                this.GroupName = groupName;
            }
       }

   }

And here is the stack trace:

02-14 03:44:02.799 I/MonoDroid( 6956): UNHANDLED EXCEPTION:
02-14 03:44:02.806 I/MonoDroid( 6956): System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
02-14 03:44:02.806 I/MonoDroid( 6956): Parameter name: index
02-14 03:44:02.806 I/MonoDroid( 6956): at System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) [0x00029] in <657aa8fea4454dc898a9e5f379c58734>:0
02-14 03:44:02.806 I/MonoDroid( 6956): at System.ThrowHelper.ThrowArgumentOutOfRangeException () [0x00000] in <657aa8fea4454dc898a9e5f379c58734>:0
02-14 03:44:02.806 I/MonoDroid( 6956): at System.Collections.Generic.List1[T].get_Item (System.Int32 index) [0x00009] in <657aa8fea4454dc898a9e5f379c58734>:0 02-14 03:44:02.806 I/MonoDroid( 6956): at Cadenza.Collections.OrderedDictionary2[TKey,TValue].get_Item (System.Int32 index) [0x00000] in D:\agent_work\1\s\Xamarin.Forms.Core\OrderedDictionary.cs:102
02-14 03:44:02.806 I/MonoDroid( 6956): at Xamarin.Forms.Internals.TemplatedItemsList2[TView,TItem].GetGroup (System.Int32 index) [0x0000a] in D:\agent\_work\1\s\Xamarin.Forms.Core\TemplatedItemsList.cs:569 02-14 03:44:02.806 I/MonoDroid( 6956): at Xamarin.Forms.Internals.TemplatedItemsList2[TView,TItem].Xamarin.Forms.ITemplatedItemsList.GetGroup (System.Int32 index) [0x00000] in D:\agent_work\1\s\Xamarin.Forms.Core\TemplatedItemsList.cs:574
02-14 03:44:02.806 I/MonoDroid( 6956): at Xamarin.Forms.Platform.Android.ListViewAdapter.get_Count () [0x0002d] in D:\agent_work\1\s\Xamarin.Forms.Platform.Android\Renderers\ListViewAdapter.cs:83
02-14 03:44:02.807 I/MonoDroid( 6956): at Android.Widget.BaseAdapter.n_GetCount (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in :0
02-14 03:44:02.807 I/MonoDroid( 6956): at (wrapper dynamic-method) System.Object:2a8e8f55-c6c2-48fb-8197-325ddf3d9397 (intptr,intptr)
02-14 03:44:02.816 W/art ( 6956): JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable

Thank you in advance

Posts

  • SergeyIvanov.9607SergeyIvanov.9607 USMember ✭✭
    edited March 2018

    I've experienced the same issue and after some searching around I've fount an item in Xamarin bugbase: https : // bugzilla.xamarin.com/show_bug.cgi?id=29288 that gave an answer.

    In this case the collection in ViewModel is updated from a thread other than UI here:

    public async Task LoadDataAsync()
    {
    await Task.Run( () =>
    {
    //here i create groups (GroupedClassif ): GroupedClassif.Add(group);
    });
    }

    There are two solutions to this as Eric Maupin suggested, one of them is to use Device.BeginInvokeOnMainThread (Worked for me)

  • LippelLippel DEMember ✭✭
    edited June 2018

    @SergeyIvanov.9607
    Hey, what did you put into the BeginInvokeOnMainThread action? Adding groups to the GroupedClassif?

    EDIT: I moved my code that adds groups to the groups list into the Device.BeginInvokeOnMainThread action and it seems to work.
    The indexing exception doesnt occur anymore.

    Lets see for how long this works :)

    Thanks a lot so far!

  • SergeyIvanov.9607SergeyIvanov.9607 USMember ✭✭

    I'm sorry for the wrapped code, I couldn't edit it now, guess it was too long after I posted it.
    Here's the code
    Doing the addition inside the BeginInvokeOnMainThread is one of the solutions

    public async Task LoadDataAsync()
    {
        await Task.Run( () =>
        {
            //here i create groups (GroupedClassif ): GroupedClassif.Add(group);
            Device.BeginInvokeOnMainThread(() => { /* Add group to  the collection here instead */ });
        });
    }
    
Sign In or Register to comment.