Search code examples
xamlxamarin.forms

Xamarin Forms CollectionView ScrollTo Not working on Load


I Have XAML form using a CollectionView. I bind the view to a collection of date objects. I set the SelectedItem in Code Behind which is working as expected. I then try to use ScrollTo in code behind however it always displays the first item in the collection once the page is loaded. After the page loads I have wired an image to fire the ScrollTo event and it works as expected. Below is my code. Thanks in advance for any help!

'''
        for (int i = 0; i < 31 ; i++)
        {
            ScheduleDate date = new ScheduleDate();
            date._Date = dt.AddDays(i);
            colDates.Add(date);
        }

        cvDate.ItemsSource = colDates;
        cvDate.SelectedItem = colDates[10];
        cvDate.ScrollTo(cvDate.SelectedItem, null, ScrollToPosition.Start, true)
'''

XAML Form

'''
            <CollectionView x:Name="cvDate" Grid.Row="0" Grid.Column="1" 
                SelectionMode="Single" >
                <CollectionView.ItemsLayout>
                    <LinearItemsLayout Orientation="Horizontal"  />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Label Text="{Binding Description}"
                                            FontAttributes="Bold"
                                            FontSize="Large"
                                            HorizontalOptions="Center"
                                            VerticalOptions="Center"
                                            />
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
'''

Edit:

I wired up the OnCollectionViewScrolled event and when the following line of code is executed from OnAppearing()

cvDate.ScrollTo(cvDate.SelectedItem, null, ScrollToPosition.Start, false);

OnCollectionViewScrolled is NOT being called. However when I execute the same line of code from a button click event OnCollectionViewScrolled is being fired.


Solution

  • I am not sure what is your Description and _Date. I make a simple example for your reference.

    1. Trigger the ScrollTo in OnAppearing override method:

      protected override void OnAppearing()
       {
          cvDate.ScrollTo(cvDate.SelectedItem, null, ScrollToPosition.Start, false);
       }
      
    2. Trigger the ScrollTo with button click method:

      private void Button_Clicked(object sender, EventArgs e)
       {
           cvDate.ScrollTo(cvDate.SelectedItem, null, ScrollToPosition.Start, false);
       }
      

    The whole code:

    public partial class Page4 : ContentPage
    {
        public ObservableCollection<ScheduleDate> colDates { get; set; }
        public Page4()
        {
            InitializeComponent();
    
            colDates = new ObservableCollection<ScheduleDate>();
            for (int i = 0; i < 31; i++)
            {
                ScheduleDate date = new ScheduleDate();
                date.Description = i.ToString();
                colDates.Add(date);
            }
    
            cvDate.ItemsSource = colDates;
            cvDate.SelectedItem = colDates[10];
          
    
        }
        protected override void OnAppearing()
        {
           cvDate.ScrollTo(cvDate.SelectedItem, null, ScrollToPosition.Start, false);
    
        }
        private void Button_Clicked(object sender, EventArgs e)
        {
            //cvDate.ScrollTo(cvDate.SelectedItem, null, ScrollToPosition.Start, false);
        }
    }
    public class ScheduleDate
    {
        public string Description { get; set; }
    }
    

    Screenshot:

    enter image description here

    Update:

     <ContentPage.Content>
    
        <StackLayout>
            <CollectionView
            x:Name="cvDate"
            ItemsSource="{Binding colDates}"
            SelectionMode="Single">
                <CollectionView.ItemsLayout>
                    <LinearItemsLayout Orientation="Horizontal" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <Label
                        FontAttributes="Bold"
                        FontSize="Large"
                        HorizontalOptions="Center"
                        Text="{Binding Description}"
                        VerticalOptions="Center" />
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
            <Button Clicked="Button_Clicked"></Button>
        </StackLayout>
    
    </ContentPage.Content>