Search code examples
c#xamarinxamarin.formsxamarin.forms.collectionview

CollectionView updating ImageButton scroll repeating UI issue


I've got a CollectionView containing an ImageButton. When the image is pressed I replace a.png with b.png.

This is working fine but when I scroll down the list, every 10th item is now showing b.png!

If instead of setting the button.source, I called the line below again after saving to the DB which solves my problem but then I start at the top of the list and not at the current position I was at:

ItemsListView.ItemsSource = items;

How can I set the button.source without it creating this bug on every 10th item?

    <CollectionView x:Name="Items">
                <CollectionView.ItemTemplate>
                        <DataTemplate>
                           <ImageButton CommandParameter="{Binding Id}" Source="a.png" Clicked="OnInventoryClicked" />
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
    </CollectionView>
    void OnInventoryClicked(object sender, EventArgs e)
            {
                    var button = (sender as ImageButton);
                    var itemId = button.CommandParameter.ToString();
                    var inventoryItem = await App.Database.GetItemAsync(itemId);
                    inventoryItem.IsInInventory = !inventoryItem.IsInInventory;
                    await App.Database.SaveItemAsync(inventoryItem);
                    button.Source = inventoryItem.IsInInventory? "b.png" : "a.png";         
            }

Solution

  • You could change with the souce property.

    Xaml:

    <CollectionView x:Name="Items" ItemsSource="{Binding infos}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <!--<ImageButton
                    Clicked="OnInventoryClicked"
                    CommandParameter="{Binding Id}"
                    Source="a.png" />-->
                <ImageButton Clicked="ImageButton_Clicked" Source="{Binding image}" />
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    

    Code behind:

    public partial class MainPage : ContentPage
    {
    
        public ObservableCollection<Info> infos { get; set; }
        public MainPage()
        {
            InitializeComponent();
            infos = new ObservableCollection<Info>()
            {
                new Info{image = "pink.jpg"        },
                new Info{image = "pink.jpg"        },
                new Info{image = "pink.jpg"        },
                new Info{image = "pink.jpg"        },
                new Info{image = "pink.jpg"        },
    
            };
    
    
            this.BindingContext = this;
        }
    
        private void ImageButton_Clicked(object sender, EventArgs e)
        {
            var button = (sender as ImageButton);
            button.Source = "dog.jpg";
        }
    
    
    }
    public class Info
    {
        public string image { get; set; }
    }