[Issue] CollectionView with controls included in Xamarin Forms 5.0.0.2125

Abdulaziz Ali 1 Reputation point
2021-09-25T08:09:45.233+00:00

I found the collection view not working correctly when the template view height is a bit long specially when adding controls like button , checkbox and others , the events are firing also in other items on the list

Example:
I have list of string from 'A' to 'I' displayed as checkbox list in the collection view

Here works fine because the **item view height is small*(Clicked to A)
135201-img-0044.png

But when the item view height is long ,the click event occurs also to other items (Clicked to A and occurred also to I)
135202-img-0041.png

135221-img-0043.png

Source

XML

<?xml version="1.0" encoding="utf-8" ?>  
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
             x:Class="proj.MainPage">  
    <Grid Padding="20">  
         <CollectionView ItemsSource="{Binding Items}" VerticalOptions="FillAndExpand" >  
            <CollectionView.ItemTemplate>  
                <DataTemplate>  
                    <Grid  Margin="10" Padding="20 ">  
                        <Frame/>  
                        <StackLayout Orientation="Horizontal">  
                            <CheckBox  VerticalOptions="Center"/>  
                            <Label Text="{Binding}" VerticalOptions="Center"/>  
                        </StackLayout>  

                    </Grid>  
                </DataTemplate>  
            </CollectionView.ItemTemplate>  
        </CollectionView>  
    </Grid>  
</ContentPage>  

C#

using System.Collections.ObjectModel;  
using Xamarin.Forms;  

namespace proj  
{  
    public partial class MainPage : ContentPage  
    {  
        public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>();  
        string characters = "ABCDEFGHI";  
        public MainPage()  
        {  
            InitializeComponent();  
            for (int i = 0; i < characters.Length; i++)  
                Items.Add(characters[i].ToString());  
            BindingContext = this;  
        }         
    }  

}  

Really need for help I am absolutely stuck working in a project

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,291 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 25,996 Reputation points Microsoft Vendor
    2021-09-27T07:39:35.427+00:00

    Hello,
    Welcome to our Microsoft Q&A platform!

    It caused by the ReusableView of collection rather than its height, the collection view places them on a reuse queue rather than deleting them when they are scrolled out of the visible bounds. Such a view can then be retrieved and repurposed for a different set of content. When "A" scroll out of the screen, 'I' will reuse it, so we should reset the state of checkbox. You could use a viewmodel and refer to the follwing code to avoid this issue.

    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"  
                 x:Class="CollectionViewHeightDemo.MainPage">  
      
        <StackLayout Padding="20">  
            <CollectionView  ItemsSource="{Binding Items}" VerticalOptions="FillAndExpand" >  
                <CollectionView.ItemTemplate >  
                    <DataTemplate >  
                        <StackLayout  Margin="10" Padding="20 ">  
                        <Frame CornerRadius="10"  BorderColor="Gray">  
                            <StackLayout Orientation="Horizontal" >  
                                    <CheckBox  VerticalOptions="Center" IsChecked="{Binding IsChecked}" CheckedChanged="CheckBox_CheckedChanged" />  
                                    <Label Text="{Binding Text}" VerticalOptions="Center"/>  
                            </StackLayout>  
                        </Frame>  
                        </StackLayout>  
                    </DataTemplate>  
                </CollectionView.ItemTemplate>  
            </CollectionView>  
        </StackLayout>  
      
    </ContentPage>  
    

    CS

    namespace CollectionViewHeightDemo  
    {  
        public partial class MainPage : ContentPage  
        {  
            //public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>();  
            public ObservableCollection<ItemViewModels> Items { get; set; } = new ObservableCollection<ItemViewModels>();  
            string characters = "ABCDEFGHIGKLMNOPQ";  
            public MainPage()  
            {  
                InitializeComponent();  
                for (int i = 0; i < characters.Length; i++)  
                    Items.Add(new ItemViewModels() { Text = characters[i].ToString() }  
                        );  
                BindingContext = this;  
            }  
      
            private void CheckBox_CheckedChanged(object sender, CheckedChangedEventArgs e)  
            {  
                Console.WriteLine("CheckedChanged");  
            }  
        }  
    }  
    

    ViewModel

    namespace CollectionViewHeightDemo  
    {  
        public class ItemViewModels : INotifyPropertyChanged  
        {  
            private String _Text;  
            public String Text  
            {  
                get => _Text;  
                set  
                {  
                    if (_Text != value)  
                    {  
                        _Text = value;  
                        OnPropertyChanged();  
                    }  
                }  
            }  
            private Boolean _Checked;  
            public Boolean IsChecked  
            {  
                get => _Checked;  
                set  
                {  
                    if (_Checked != value)  
                    {  
                        _Checked = value;  
                        OnPropertyChanged();  
                    }  
                }  
            }  
            public event PropertyChangedEventHandler PropertyChanged;  
            private void OnPropertyChanged([CallerMemberName] String propertyName = "")  
            {  
                if (PropertyChanged != null)  
                {  
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));  
                }  
            }  
        }  
    }  
    

    Best Regards,
    Wenyan Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments