From 03266f580ad9bbcabfc7ce99dd25bc50aceadfbd Mon Sep 17 00:00:00 2001 From: "E.Z. Hart" Date: Mon, 6 May 2019 11:05:29 -0600 Subject: [PATCH] [iOS] Add missing null check to `SelectableItemsViewRenderer.SetupNewElement`. (#6057) * Reproduction * Automate test * Handle null element in SetupElement in the SelectableItemsViewRenderer Fixes #5949 * Add manual test instructions * Fix build errors --- .../FlagTestHelpers.cs | 17 ++++++ .../Issue5535.cs | 2 +- .../Issue5949.cs | 52 ++++++++++++++++++ .../Issue5949_1.xaml | 20 +++++++ .../Issue5949_1.xaml.cs | 26 +++++++++ .../Issue5949_2.xaml | 19 +++++++ .../Issue5949_2.xaml.cs | 61 ++++++++++++++++++++++ .../Xamarin.Forms.Controls.Issues.Shared.projitems | 22 ++++++++ .../CollectionView/SelectableItemsViewRenderer.cs | 5 ++ 9 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FlagTestHelpers.cs create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949.cs create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml.cs create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml create mode 100644 Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml.cs diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FlagTestHelpers.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FlagTestHelpers.cs new file mode 100644 index 0000000..dfd49be --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/FlagTestHelpers.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace Xamarin.Forms.Controls.Issues +{ + internal static class FlagTestHelpers + { + public static void SetTestFlag(string flag) + { + Device.SetFlags(new List(Device.Flags ?? new List()) { flag }); + } + + public static void SetCollectionViewTestFlag() + { + SetTestFlag("CollectionView_Experimental"); + } + } +} diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5535.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5535.cs index 5b0d346..fff590f 100644 --- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5535.cs +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5535.cs @@ -23,7 +23,7 @@ namespace Xamarin.Forms.Controls.Issues protected override void Init() { #if APP - Device.SetFlags(new List(Device.Flags ?? new List()) { "CollectionView_Experimental" }); + FlagTestHelpers.SetCollectionViewTestFlag(); PushAsync(new GalleryPages.CollectionViewGalleries.EmptyViewGalleries.EmptyViewSwapGallery()); #endif diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949.cs new file mode 100644 index 0000000..93a5830 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Xamarin.Forms; +using Xamarin.Forms.CustomAttributes; +using Xamarin.Forms.Internals; + +#if UITEST +using Xamarin.Forms.Core.UITests; +using Xamarin.UITest; +using NUnit.Framework; +#endif + +namespace Xamarin.Forms.Controls.Issues +{ + +#if UITEST + [Category(UITestCategories.CollectionView)] +#endif + [Preserve(AllMembers = true)] + [Issue(IssueTracker.Github, 5949, "CollectionView cannot access a disposed object.", + PlatformAffected.iOS)] + public class Issue5949 : TestContentPage + { + protected override void Init() + { + FlagTestHelpers.SetCollectionViewTestFlag(); + Appearing += Issue5949Appearing; + } + + private void Issue5949Appearing(object sender, EventArgs e) + { + Application.Current.MainPage = new Issue5949_1(); + } + +#if UITEST + [Test] + public void DoNotAccessDisposedCollectionView() + { + RunningApp.WaitForElement("Login"); + RunningApp.Tap("Login"); + + RunningApp.WaitForElement(Issue5949_2.BackButton); + RunningApp.Tap(Issue5949_2.BackButton); + + RunningApp.WaitForElement("Login"); + } +#endif + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml new file mode 100644 index 0000000..88952f6 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml.cs new file mode 100644 index 0000000..f724a01 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_1.xaml.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Xamarin.Forms; +using Xamarin.Forms.Internals; +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Controls.Issues +{ +#if APP + [XamlCompilation(XamlCompilationOptions.Compile)] +#endif + [Preserve(AllMembers = true)] + public partial class Issue5949_1 : MasterDetailPage + { + public Issue5949_1() + { +#if APP + InitializeComponent(); +#endif + } + } +} \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml new file mode 100644 index 0000000..f1ad952 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml.cs new file mode 100644 index 0000000..e8008a9 --- /dev/null +++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue5949_2.xaml.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using Xamarin.Forms.Internals; +using Xamarin.Forms.Xaml; + +namespace Xamarin.Forms.Controls.Issues +{ +#if APP + [XamlCompilation(XamlCompilationOptions.Compile)] +#endif + [Preserve(AllMembers = true)] + public partial class Issue5949_2 : ContentPage + { + public const string BackButton = "5949GoBack"; + public const string ToolBarItem = "Login"; + + public Issue5949_2() + { +#if APP + InitializeComponent(); + ToolbarItems.Add(new ToolbarItem(ToolBarItem, null, () => Navigation.PushAsync(LoginPage()))); + BindingContext = new _5949ViewModel(); +#endif + } + + [Preserve(AllMembers = true)] + class _5949ViewModel + { + public _5949ViewModel() + { + Items = new List + { + "one", "two", "three" + }; + } + + public List Items { get; set; } + } + + ContentPage LoginPage() + { + var page = new ContentPage + { + Title = "Issue 5949" + }; + + var button = new Button { Text = "Back", AutomationId = BackButton }; + + button.Clicked += ButtonClicked; + + page.Content = button; + + return page; + } + + private void ButtonClicked(object sender, EventArgs e) + { + Application.Current.MainPage = new Issue5949_1(); + } + } +} \ No newline at end of file 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 fa0c91b..e6ce684 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 @@ -12,6 +12,7 @@ + Code @@ -461,6 +462,15 @@ Code + + + Issue5949_1.xaml + Code + + + Issue5949_2.xaml + Code + @@ -1180,4 +1190,16 @@ MSBuild:UpdateDesignTimeXaml + + + Designer + MSBuild:Compile + + + + + Designer + MSBuild:Compile + + \ No newline at end of file diff --git a/Xamarin.Forms.Platform.iOS/CollectionView/SelectableItemsViewRenderer.cs b/Xamarin.Forms.Platform.iOS/CollectionView/SelectableItemsViewRenderer.cs index 653a0c4..3cec808 100644 --- a/Xamarin.Forms.Platform.iOS/CollectionView/SelectableItemsViewRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/CollectionView/SelectableItemsViewRenderer.cs @@ -36,6 +36,11 @@ namespace Xamarin.Forms.Platform.iOS base.SetUpNewElement(newElement); + if (newElement == null) + { + return; + } + SelectableItemsViewController.UpdateSelectionMode(); SelectableItemsViewController.UpdateNativeSelection(); } -- 2.7.4