简体   繁体   中英

How to reflect changes made in CarouselView.ItemsSource in the carouselView? (Xamarin Forms)

I was working on my Xamarin.Forms app, trying to make the Items inside my scrollview change their TransitionX property when scrolling, the problem is that once the scrollview has been shown the items inside it will not change as the source does unless you reassign the carouselview.ItemSource, but I can't do this because it would be extremely inefficient and the scrolling would be awful. So is there any way to reflect the changes made in the source, in the carouselView dynamically?

Here goes my code, I have written comments to make it as clear as possible: CarouselView:

<MasterDetailPage.Detail>
        <ContentPage Title="title">
            <StackLayout
                x:Name="page">

                <CarouselView
                    x:Name="carousel" 

                    VerticalOptions="StartAndExpand"
                    HorizontalOptions="StartAndExpand"

                    BackgroundColor="Transparent"

                    Scrolled="carousel_Scrolled">

                    <CarouselView.Behaviors>
                        <behaviors:CarouselViewParallaxBehavior ParallaxOffset="100"/>
                    </CarouselView.Behaviors>

                    <CarouselView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid>
//Here goes more content which is irrelevant for this matter
                                </Grid>

                                <Image
                                    Source="{Binding ImageSrc}"
                                    BackgroundColor="Transparent"
                                    HeightRequest="500"

//This is the property I am trying to change when scrolling
                                    TranslationX="{Binding Position}"

                                    VerticalOptions="Center"
                                    HorizontalOptions="Center"
                                    Margin="0,-160,0,0"></Image>

                            </Grid>
                        </DataTemplate>
                    </CarouselView.ItemTemplate>
                </CarouselView>

            </StackLayout>
        </ContentPage>
    </MasterDetailPage.Detail>

My xaml.cs code:

[XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class HomePage : MasterDetailPage
    {
        private List<Color> _backgroundColorscount = new List<Color>();
        private List<Color> _backgroundColors = new List<Color>();
        private List<Product> Items;
        private static double position = 0;

        public HomePage()
        {
            InitializeComponent();

//These are the items of my carouselView
            Items = new List<Product>()
            {
                // Just create some dummy data here for now.
                new Product{Title = "Classic burguer", Price = "124$", ImageSrc = "Burguer.png", StartColor = Color.FromHex("#DF8000"), EndColor = Color.FromHex("#DCD800")},
                new Product{Title = "Classic burguer", Price = "124$", ImageSrc = "Burguer.png", StartColor = Color.FromHex("#15DE00"), EndColor = Color.FromHex("#BADE00")},
                new Product{Title = "Classic burguer", Price = "124$", ImageSrc = "Burguer.png", StartColor = Color.FromHex("#00DEAD"), EndColor = Color.FromHex("#DCD800")}
            };

            carousel.ItemsSource = Items;
        }


        private void carousel_Scrolled(object sender, ItemsViewScrolledEventArgs e)
        {
//Here is what I am trying to do (I wrote it right now to show the problem)
            Items[0].Position = position - 10;
// the position property in Items[0] is changed, but the change is not reflected in the carouselView
        }
    }

My Model class:

    class Product
    {
        #region Bindings
        //Item views 
        public string Title { get; set; }
        public string Price { get; set; }
        public string ImageSrc { get; set; }
        public string Description { get; set; }

        // Gradient colors
        private Color startColor;
        public Color StartColor 
        {
            get
            {
                return startColor;
            }

            set
            {
                startColor = value;
            }
        }

        private Color endColor;
        public Color EndColor 
        {
            get
            {
                return endColor;
            }

            set
            {
                endColor = value;
            } 
        }

        private Color backgroundColor;
        public Color BackgroundColor
        {
            get 
            {
                if (startColor != null && endColor != null)
                    backgroundColor = GetBackGroundColor();

                return backgroundColor;
            }
        }

        //Item Properties 
        private double _position;
        public double Position
        {
            get
            { 
                return _position; 
            }
            set
            { 
                _position = value; 
                OnPropertyChanged(); 
            }
        }

        private double _scale;
        public double Scale
        {
            get { return _scale; }
            set
            {
                _scale = value;
                OnPropertyChanged();
            }
        }
        #endregion

        public Product()
        {
            Scale = 1;
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

And that is all, if you need more code or info I will provide it to you as soon as I see your request. Thank you all for your time, have a good day.

Well use bindings to make our life easier:

In your XAML:

<ListView ItemsSource="{Binding Items}" ...../>

In your C# side Items will be an observable collection

public ObservableCollection<Product> Items { get; set; }

Also, you won't need

carousel.ItemsSource = Items;

Rest would stay the same now as soon as you make any changes to the collection the carousel should change too.

Note: All properties of the Product class would need to notify on property changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM