xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.64k stars 1.88k forks source link

[Bug] Carousel view inside carousel view conflict on position #15794

Open Vannoctar2 opened 11 months ago

Vannoctar2 commented 11 months ago

Description

Bonjour,

Je vous contacte car j'ai un bug dans mon programme que j'ai pu reproduire. J'ai un carouselview imbriqué dans un autre. Le défilement à l'intérieur ne fonctionnait pas alors j'ai désactivé celui du parent et je l'ai fait manuellement. Le problème ne se pose pas là.

Quand on défile au niveau du carousel parent, tout va bien. Quand on défile au niveau du carousel enfant, tout va bien.

Le soucis se pose quand on essaie d'ajouter un nouvel item dans la collection du parent.

Voici mon code. Très simple à reproduire 👍

TestPage.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"
             xmlns:model="clr-namespace:MathomicsEnseignant.Views.SubViews"
             x:Class="MathomicsEnseignant.Views.SubViews.TestPage"
             x:Name="_TestPage">
    <ContentPage.Content>
      <StackLayout>
            <CarouselView
                x:Name="_carousel"
                ItemsSource="{Binding Items}"                
                IsSwipeEnabled="False">
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout>
                            <Label Text="{Binding .}" TextColor="Black" FontSize="Header" HorizontalTextAlignment="Center"/>
                            <model:Inside/>
                        </StackLayout>
                    </DataTemplate>
                </CarouselView.ItemTemplate>

            </CarouselView>
            <StackLayout Orientation="Horizontal">
                <Button Text="Left"  Clicked="SwipeLeft"/>
                <Button Text="AddItem" Command="{Binding CommandAddItem}"/>
                <Button Text="Right" Clicked="SwipeRight"/>
            </StackLayout>
        </StackLayout>
  </ContentPage.Content>
</ContentPage>

TestPage.xaml.cs

using MathomicsEnseignant.Test.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MathomicsEnseignant.Views.SubViews
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class TestPage : ContentPage
    {
        public TestPage()
        {
            InitializeComponent();
            this.BindingContext = new TestPageViewModel();

        }

        public void SwipeLeft(object sender, EventArgs e)
        {
            ObservableCollection<string> collection = (ObservableCollection<string>)this._carousel.ItemsSource;
            int currentIndex = collection.IndexOf((string)_carousel.CurrentItem);
            int nextIndex = currentIndex - 1;
            if (nextIndex < 0) nextIndex = collection.Count - 1;
            _carousel.ScrollTo(nextIndex);
            _carousel.Position = nextIndex;
            _carousel.CurrentItem = collection[nextIndex];
        }

        public void SwipeRight(object sender, EventArgs e)
        {
            ObservableCollection<string> collection = (ObservableCollection<string>)this._carousel.ItemsSource;

            int currentIndex = collection.IndexOf((string)_carousel.CurrentItem);
            int nextIndex = currentIndex + 1;
            if (nextIndex >= collection.Count) nextIndex = 0;

            _carousel.ScrollTo(nextIndex);
            _carousel.Position = nextIndex;
            _carousel.CurrentItem = collection[nextIndex];
        }

    }
}

TestPageViewModel:

using MathomicsEnseignant.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Xamarin.Forms;

namespace MathomicsEnseignant.Test.ViewModels
{
    public class TestPageViewModel: BaseViewModel
    {
        public ObservableCollection<String> Items { get; set; } = new ObservableCollection<string>();

        public Command CommandAddItem { get; set; } 

        public TestPageViewModel()
        {
            CommandAddItem = new Command(AddItem);
            for (int i = 0; i < 5; i++) this.Items.Add(this.Items.Count + "");
        }

        public void AddItem()
        {
            this.Items.Add(this.Items.Count + "");
        }

    }
}

Inside.xaml:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MathomicsEnseignant.Views.SubViews.Inside"
             x:Name="_inside">
    <ContentView.Content>
      <StackLayout>
            <CarouselView
                ItemsSource="{Binding Items2}" >
                <CarouselView.ItemTemplate>
                    <DataTemplate>
                        <Label Text="{Binding .}" TextColor="Black" FontSize="Header" HorizontalTextAlignment="Center"/>
                    </DataTemplate>
                </CarouselView.ItemTemplate>
            </CarouselView>
        </StackLayout>
  </ContentView.Content>
</ContentView>

Inside.xaml.cs:

using MathomicsEnseignant.Test.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace MathomicsEnseignant.Views.SubViews
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Inside : ContentView
    {
        public Inside()
        {
            InitializeComponent();
            this.BindingContext = new InsidePageViewModel();

        }
    }
}

InsidePageViewModel:

using MathomicsEnseignant.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Xamarin.Forms;

namespace MathomicsEnseignant.Test.ViewModels
{
    public class InsidePageViewModel: BaseViewModel
    {
        public ObservableCollection<String> Items2 { get; set; } = new ObservableCollection<string>();

        public InsidePageViewModel()
        {
            for (int i = 0; i < 5; i++) this.Items2.Add("Inside " + this.Items2.Count + "");
        }

    }
}

Steps to Reproduce

  1. Faite défiler les éléments du parents avec les boutons "left" and "right"
  2. Faite défiler le carousel enfant.
  3. Cliquez sur AddItem (bouton central)

Expected Behavior

Le dernier Item doit se rajouter à la fin du carousel view. On garde la même view et le carouselview à l'intérieur de change pas.

Actual Behavior

On reste sur la même page, mais le carouselview semble s'être déplacé sur un autre item du parent.

Basic Information

Je lance l'application sur un emulateur android pixel_5 api_30

Build Logs

No log

Screenshots

Pas de capture d'écran, la description suffit.

Vannoctar2 commented 11 months ago

Bug Xamarin.webm

Je joins une vidéo pour montrer le bug.

Vannoctar2 commented 11 months ago

Up.

bricefriha commented 10 months ago

Up.

I think the reason why your issue gets no attention is because you stated it in French 🙂

Vannoctar2 commented 10 months ago

Up.

I think the reason why your issue gets no attention is because you stated it in French 🙂

Okay , thanks. I rewrite this post in english.