CarouselView throws System.IndexOutOfRangeException when ObservableCollection is changed

Marius A 26 Reputation points
2021-07-07T14:07:48.41+00:00

I have created a Xamarin Forms Shell App. The app has multiple tabs which route to different pages. On one of the pages I use a CarouselView.
The ItemsSource of the CarouselView is an ObservableCollection<ContentView> inside the ViewModel. The ObservableCollection gets updated via the OnAppearing()-method of the page by calling an update function in the ViewModel. The first time I navigate to the page the CarouselView works fine.
However, when I change the tab and then return to the tab with the CarouselView, the following exception is thrown:

System.IndexOutOfRangeException: 'Can't set CarouselView to position -1. ItemsSource has 3 items.'

This only happens on Android.

Steps to reproduce:

  1. Create Xamarin Forms tabbed shell App
  2. In the first tab add a CarouselView to the page
  3. Update CarouselView inside OnAppearing()
  4. Go to another tab
  5. Return to tab with CarouselView in it

Any workaround would be highly appreciated. Thank you!

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,283 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 67,446 Reputation points Microsoft Vendor
    2021-07-08T06:25:54.407+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    I follow you steps, But I do not meet this issue.

    I can run it normally like following screenshot.

    112707-image.png

    I add my code to AboutPage.xaml

       <?xml version="1.0" encoding="utf-8" ?>  
       <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
                    x:Class="ShellCarouselView.Views.AboutPage"  
                    xmlns:vm="clr-namespace:ShellCarouselView.ViewModels"  
                    Title="{Binding Title}">  
             
           
           <ContentPage.Resources>  
               <ResourceDictionary>  
                   <Color x:Key="Accent">#96d1ff</Color>  
               </ResourceDictionary>  
           </ContentPage.Resources>  
           <CarouselView ItemsSource="{Binding ItemsView}">  
               <CarouselView.ItemTemplate>  
                   <DataTemplate>  
                       <ContentView Content="{Binding Content}" />  
                   </DataTemplate>  
               </CarouselView.ItemTemplate>  
         
           </CarouselView>  
         
             
       </ContentPage>  
    

    Here is background code of AboutPage.xaml

       public partial class AboutPage : ContentPage  
           {  
               AboutViewModel aboutViewModels;  
               public AboutPage()  
               {  
                   InitializeComponent();  
         
                    aboutViewModels = new AboutViewModel();  
         
                   BindingContext = aboutViewModels;  
               }  
               public static int value = 1;  
               protected override void OnAppearing()  
               {  
                   base.OnAppearing();  
         
                 //  aboutViewModels.Items.Add(new Item() { Text = "tesx"+ (value++) });  
         
                   aboutViewModels.ItemsView.Add(new View1());  
                 
         
               }  
           }  
    

    Here is my viewModel.

       public class AboutViewModel : BaseViewModel  
           {  
               public ObservableCollection<Item> Items { get; }  
         
               public ObservableCollection<ContentView> ItemsView { get; }  
               public AboutViewModel()  
               {  
                   Items = new ObservableCollection<Item>();  
                   ItemsView = new ObservableCollection<ContentView>();  
                     Title = "About";  
                   OpenWebCommand = new Command(async () => await Browser.OpenAsync("https://aka.ms/xamarin-quickstart"));  
               }  
         
               public ICommand OpenWebCommand { get; }  
           }  
    

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.