question

MariusA-0359 avatar image
0 Votes"
MariusA-0359 asked LeonLu-MSFT edited

CarouselView throws System.IndexOutOfRangeException when ObservableCollection is changed

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!

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

LeonLu-MSFT avatar image
1 Vote"
LeonLu-MSFT answered LeonLu-MSFT edited

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.




image.png (34.7 KiB)
· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello LeonLu-MSFT,

thanks for your reply!
You might be able to reproduce the error by removing or updating an existing item in your ObservableCollection (in your example you only add a new item).
In case this does not reproduce the error, you can take a look at the repository I created with a minimalistic example based on your code:
https://github.com/moccajoghurt/CarouselBug

Let me know if you can reproduce this error and hopefully find a workaround.

Thank you!

0 Votes 0 ·

I have found a workaround. Instead of directly overwriting the ContentViews, you can update ContentView.Content:

 ContentViews[0].Content = new View1();
0 Votes 0 ·

Did you solved this issue by ContentViews[0].Content = new View1();?

0 Votes 0 ·
Show more comments