Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[Bug] Binding CurrentItem of CarouselView overwrites value of backing property when CarouselView initializes #12855

Open
BioTurboNick opened this issue Nov 15, 2020 · 4 comments

Comments

@BioTurboNick
Copy link

BioTurboNick commented Nov 15, 2020

Description

When CarouselView initializes, it forces CurrentItem to be set to the first item in its collection. If CurrentItem is bound to a backing property, that causes it to be overwritten. Part of the issue may be that setting CurrentItem doesn't set Position?

Steps to Reproduce

  1. Initialize a property to a value that doesn't appear first in a CarouselView.
  2. Bind CarouselView.CurrentItem to the property.
  3. Run the application.

Expected Behavior

CarouselView.CurrentItem should take on the value of its backing property at initialization and the backing property should be unchanged.

Actual Behavior

CarouselView.CurrentItem is initialized to the first item in ItemsSource, which is propagated to the property bound to CurrentItem.

Basic Information

  • Version with issue: 4.8.x, 5.0.0-pre3
  • Last known good version: 4.7
  • IDE: Visual Studio 16.8.1
  • Platform Target Frameworks:
    • Android: 11.0

Reproduction Link

CarouselInitializationBinding.zip

Workaround

No, it takes control. I can't figure out how to hook it so that the position changes after loading. EDIT: see next post.

@BioTurboNick BioTurboNick added s/unverified New report that has yet to be verified t/bug 🐛 labels Nov 15, 2020
@samhouts samhouts added this to New in Triage Nov 15, 2020
@BioTurboNick
Copy link
Author

BioTurboNick commented Nov 15, 2020

Found an ugly workaround:

        bool skipNext;

        private void Carousel_CurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
        {
            // workaround for initial set bug

            bool isBad = new StackTrace().GetFrames().Select(x => x.GetMethod().Name).Any(x => x.Contains("SetUpNewElement"));

            if (isBad)
            {
                if (!skipNext)
                {
                    skipNext = true;
                    ((CarouselView)sender).Position = _GridLayouts.IndexOf((GridLayout)e.PreviousItem);
                }
                else
                    skipNext = false;

                return;
            }

            // your code
        }

You have to set Position, not CurrentItem, here. And the skipping thing may be specific to how I'm doing things. GridLayout is the type of item the CarouselView has in its ItemsSource.

@BioTurboNick
Copy link
Author

BioTurboNick commented Nov 15, 2020

Ahhhhh the workaround breaks when Loop == false for some reason??? But when Loop == true, the displayed item is out of order and changes as soon as you touch the carousel.

😩

@BioTurboNick
Copy link
Author

Found an actual workaround:

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);

            gridLayoutCarousel.ScrollTo(_GridLayouts.IndexOf(_viewModel.Hemocytometer.GridLayout));    // workaround for initial set bug
        }

        private void GridLayoutCarousel_CurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
        {
            // workaround for initial set bug

            bool isBad = new StackTrace().GetFrames().Select(x => x.GetMethod().Name).Any(x => x.Contains("UpdateAdapter"));

            if (isBad)
                return;

            // handle the event
        }

OnSizeAllocated fires after the control is in place. Still need to avoid handling any events during the initialization.

@jsuarezruiz jsuarezruiz added this to Backlog in CarouselView via automation Nov 16, 2020
@jsuarezruiz jsuarezruiz added e/3 🕒 3 and removed s/unverified New report that has yet to be verified labels Nov 16, 2020
@jsuarezruiz jsuarezruiz moved this from New to Ready For Work in Triage Nov 16, 2020
@JosephHarvey-Xamarin
Copy link

I'm having the same issue. Putting in Task.Delay on setting the backing property can help, but it's a bad work around.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
CarouselView
  
Backlog
Triage
  
Ready For Work
Development

No branches or pull requests

3 participants