From bfd915d6963281380773cd1794ffba7004ac80ed Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Wed, 11 Sep 2019 17:31:29 -0600 Subject: [PATCH] Leave BindingContext intact when recycling TemplatedItemViewHolder (#7426) fixes #6889 Fixes #6889 --- .../Issue6889.cs | 356 +++++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 1 + .../CollectionView/TemplatedItemViewHolder.cs | 3 +- 3 files changed, 358 insertions(+), 2 deletions(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6889.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6889.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6889.cs new file mode 100644 index 0000000..ea70f17 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue6889.cs @@ -0,0 +1,356 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; +using Xamarin.Forms.PlatformConfiguration; +using Xamarin.Forms.PlatformConfiguration.iOSSpecific; +using System.Threading.Tasks; + +#if UITEST +using Xamarin.Forms.Core.UITests; +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ +#if UITEST + [NUnit.Framework.Category(UITestCategories.CollectionView)] +#endif + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 6889, "Labels disappearing in CollectionView", PlatformAffected.Android)] + public class Issue6889 : TestNavigationPage + { + protected override void Init() + { +#if APP + Device.SetFlags(new List(Device.Flags ?? new List()) { "CollectionView_Experimental" }); + + PushAsync(CreateRoot()); +#endif + } + + public ContentPage CreateRoot() + { + var page = new ContentPage { Title = "Issue6889" }; + + var layout = new StackLayout(); + + var instructions = new Label { Text = "Scroll the CollectionView below up and down quickly several times." + + " If any rows of labels disappear, this test has failed" }; + + layout.Children.Add(instructions); + + var cv = new CollectionView(); + + var template = new DataTemplate(() => { + var grid = new Grid + { + ColumnDefinitions = new ColumnDefinitionCollection + { + new ColumnDefinition { Width = GridLength.Auto }, + new ColumnDefinition { Width = GridLength.Auto } + } + }; + + var label1 = new Label { HorizontalOptions = LayoutOptions.Start }; + label1.SetBinding(Label.TextProperty, new Binding("Text1")); + grid.Children.Add(label1); + Grid.SetColumn(label1, 0); + + var label2 = new Label { HorizontalOptions = LayoutOptions.StartAndExpand }; + label2.SetBinding(Label.TextProperty, new Binding("Text2")); + grid.Children.Add(label2); + Grid.SetColumn(label2, 1); + + return grid; + }); + + cv.ItemTemplate = template; + cv.SetBinding(ItemsView.ItemsSourceProperty, new Binding("SampleList")); + + layout.Children.Add(cv); + + page.Content = layout; + + page.BindingContext = new _6889MainViewModel(); + + return page; + } + } + + [Preserve(AllMembers = true)] + public class _6889TextModel + { + public string Text1 { get; set; } + public string Text2 { get; set; } + } + + [Preserve(AllMembers = true)] + public class _6889MainViewModel + { + public _6889MainViewModel() + { + SampleList = new ObservableCollection<_6889TextModel> + { + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + new _6889TextModel { Text1="Text1",Text2="Text2"}, + }; + } + + public ObservableCollection<_6889TextModel> SampleList { get; set; } + } +} diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems index 61d71b4..2b2301f 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems @@ -18,6 +18,7 @@ + diff --git a/Xamarin.Forms.Platform.Android/CollectionView/TemplatedItemViewHolder.cs b/Xamarin.Forms.Platform.Android/CollectionView/TemplatedItemViewHolder.cs index 4dcf53b..31d8eb5 100644 --- a/Xamarin.Forms.Platform.Android/CollectionView/TemplatedItemViewHolder.cs +++ b/Xamarin.Forms.Platform.Android/CollectionView/TemplatedItemViewHolder.cs @@ -34,7 +34,6 @@ namespace Xamarin.Forms.Platform.Android public void Recycle(ItemsView itemsView) { - View.BindingContext = null; itemsView.RemoveLogicalChild(View); } @@ -51,7 +50,7 @@ namespace Xamarin.Forms.Platform.Android _selectedTemplate = template; } - _itemContentView.HandleItemSizingStrategy(reportMeasure, size); + _itemContentView.HandleItemSizingStrategy(reportMeasure, size); // Set the binding context before we add it as a child of the ItemsView; otherwise, it will // inherit the ItemsView's binding context -- 2.7.4