Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS: When changing the position after ItemsSource is changed, the item order is invalid #570

Open
irinakush opened this issue Apr 27, 2020 · 1 comment

Comments

@irinakush
Copy link

Description

By design, when ItemsSource is changed, carousel keeps the position. Attempt to change the position after ItemsSource is changed results in invalid order.

Platform

iOS (tested in 13.1.3, 13.3.1, 13.4.1)

Sample project

The Demo project files from the repository were updated to demonstrate the issue.

MainPage.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="Demo.MainPage"
    xmlns:cv="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions"
    xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms">

    <StackLayout>
        <cv:CarouselViewControl x:Name="carousel" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
        ItemsSource="{Binding MyItemsSource}"
        Position="{Binding Position}"       
        InterPageSpacing="10"
        PositionSelectedCommand="{Binding MyCommand}"
        PositionSelected="Handle_PositionSelected"
        Scrolled="Handle_Scrolled"
        Orientation="Horizontal">
            <cv:CarouselViewControl.ItemTemplate>
                <DataTemplate>
                    <Label Text="{Binding Name}" FontSize="Large" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" HorizontalOptions="Fill" VerticalOptions="Fill"></Label>
                </DataTemplate>
            </cv:CarouselViewControl.ItemTemplate>
        </cv:CarouselViewControl>

        <Button Text="Reset" Command="{Binding ResetCmd}" VerticalOptions="End" HeightRequest="100"/>
        <Label Text="{Binding PositionStr}" VerticalOptions="End" FontSize="Large" HeightRequest="100" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"></Label>
    </StackLayout>
</ContentPage>

MainViewModel.cs

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Input;
using CarouselView.FormsPlugin.Abstractions;
using FFImageLoading.Forms;
using Xamarin.Forms;

namespace Demo
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public Command ResetCmd { get; set; }

        private int _position;
        public int Position
        {
            get => _position;
            set
            {
                _position = value;
                OnPropertyChanged(nameof(Position));
                OnPropertyChanged(nameof(PositionStr));
            }
        }

        public string PositionStr
        {
            get => Position.ToString();
        }

        public MainViewModel()
        {
            MyItemsSource = new ObservableCollection<Item> {
                    new Item { Name = "Page 1"},
                    new Item { Name = "Page 2"},
                    new Item { Name = "Page 3"},
                    new Item { Name = "Page 4"}
            };

            ResetCmd = new Command(() =>
            {
                MyItemsSource = new ObservableCollection<Item> {
                    new Item { Name = "Page 5"},
                    new Item { Name = "Page 6"},
                    new Item { Name = "Page 7"},
                    new Item { Name = "Page 8"}
            };
                Position = 0;
                OnPropertyChanged(nameof(Position));
            });

            MyCommand = new Command(() =>
            {
                Debug.WriteLine("Position selected.");
            });
        }

        ObservableCollection<Item> _myItemsSource;
        public ObservableCollection<Item> MyItemsSource
        {
            set
            {
                _myItemsSource = value;
                OnPropertyChanged("MyItemsSource");
            }
            get
            {
                return _myItemsSource;
            }
        }

        public Command MyCommand { protected set; get; }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }

    public class Item
    {
        public string Name { get; set; }
    }
}

Steps

  1. Run the project
  2. Swipe to the last page - Page 4
  3. Press Reset button, which sets Position to 0
  4. Swipe
    Expected: Page 6, Position 1
    Actual: Page 8, Position 3
@alexrainman
Copy link
Owner

Working on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants