Xamarin.forms: [Android, iOS] While using CarouselView, changes in the first five items will be automatically applied to the next items.[Bug]

Created on 14 Jan 2020  路  6Comments  路  Source: xamarin/Xamarin.Forms

Description

While populating the carousel's items more than 5, it reuses the remaining items. For example, changes on 5 items will reflect in 10 items.

Steps to Reproduce

  1. Perform any operation like toggle the switch, or type anything in the entry or check the CheckBox in the first view

  2. Then scroll to see page 6. Whatever operations you have performed in the first view will be reflected in the sixth view.

Expected Behavior

Changes did not occur until the user performs any action.

Actual Behavior

Changes of the first five items will be automatically applied to the next items.

Basic Information

Version with issue: 4.4.0.991477

Platform Target Frameworks: Xamarin.Forms Android, Xamarin.Forms iOS

Affected Devices: Checked with one plus and moto device.

Reproduction Link

Sample

carouselview collectionview blocker 3 Android iOS 馃崕 bug

Most helpful comment

Why it's still in todo? This bug seems to be really critical.

All 6 comments

looks like a reuse problem

Any update or timeline for the fix available

Why it's still in todo? This bug seems to be really critical.

This is a issue not only with CarouselView but CollectioView too.
we are taking a look now.

@rmarinho CollectionView - The same applies for any animations inside ViewCell, if 1st viewcell has an animation in progress, scroll down and the same animation repeats at 7th ,14th ... ViewCells (number might be different depending on Device height)

@HemalathaMarikuma-syncfusion

While populating the carousel's items more than 5, it reuses the remaining items.

This is by design. The CarouselView is based on CollectionView, which uses virtualization to achieve its performance.

Creating Views (the cross-platform elements and their underlying native elements) is relatively expensive in terms of CPU and memory. For a CollectionView which may be bound to hundreds or even many thousands of data items, creating a View for every single item would be very slow (if not impossible). Instead, the CollectionView only creates enough Views to display the items currently on the screen (plus a few). As the Views are scrolled off the screen, they are not destroyed; rather, they are added to a pool for reuse later. As new Views are needed, the Views already in the pool are reused. This means that a CollectionView can handle many, many items while only using the resources to display a few.

The mechanism for creating these Views is the ItemTemplate. The ItemTemplate is a DataTemplate which takes a data item from the source and uses it to create a View which is bound to that data item. It is a _DataTemplate_; the _data_ is the mechanism for managing any state (e.g., whether a CheckBox is checked, or what text should appear in a Label).

You have created a DataTemplate which includes a Switch, an Entry, and several CheckBoxes which are not bound to any of the data in the data item. There is nothing to manage their state. When the Views are scrolled off the screen, they go into the pool for reuse later. When a View is needed, one is pulled from the pool and bound to a data item. The controls which have no binding to the data item just keep whatever state they had when they went into the pool.

In the case of the attached sample, the way to address this is to manage the state of all of these controls in your view model. In your Model class, add properties for the state of the controls:

public class Model : INotifyPropertyChanged { 
...

    // Control state properties
    public bool SwitchData { get; set; }
    public bool Check0 { get; set; }
    public bool Check1 { get; set; }
    public bool Check2 { get; set; }
    public bool Check3 { get; set; }
    public string EntryData { get; set; }
}

and update your DataTemplate to bind those controls:

<Grid>
    <StackLayout Grid.Row="0">
        <Switch OnColor="Red" IsToggled="{Binding SwitchData}"/>
        <CheckBox IsChecked="{Binding Check0}" />
        <CheckBox IsChecked="{Binding Check1}" />
        <CheckBox IsChecked="{Binding Check2}" />
        <CheckBox IsChecked="{Binding Check3}" />
        <Entry Text="{Binding EntryData}" />
        <Label Text="{Binding ChoiceA}" />
    </StackLayout>
</Grid>

Make these changes to your sample, and you'll no longer see changes in the first item affecting later items.

Since this is by design, I am closing this issue. If I've misunderstood something about the original report or failed to address the problem, comment here and make sure to include @hartez and we can re-open this if necessary.

Was this page helpful?
0 / 5 - 0 ratings