Fix shell to correctly pick visible item (#8009)
authorShane Neuville <shneuvil@microsoft.com>
Tue, 15 Oct 2019 18:44:22 +0000 (12:44 -0600)
committerGerald Versluis <gerald.versluis@microsoft.com>
Tue, 15 Oct 2019 18:44:22 +0000 (20:44 +0200)
- when items are removed

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue8008.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Core/Shell/Shell.cs

diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue8008.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue8008.cs
new file mode 100644 (file)
index 0000000..6b5d13b
--- /dev/null
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+
+#if UITEST
+using Xamarin.UITest;
+using NUnit.Framework;
+using Xamarin.Forms.Core.UITests;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+       [Preserve(AllMembers = true)]
+       [Issue(IssueTracker.Github, 8008, "Removing Shell Item can cause Shell to try and set a MenuItem as the default visible item")]
+#if UITEST
+       [NUnit.Framework.Category(UITestCategories.Shell)]
+#endif
+       public class Issue8008 : TestShell
+       {
+               ShellItem item1;
+               protected override void Init()
+               {
+                       item1 = AddContentPage();
+
+                       Items.Add(new MenuShellItem(new MenuItem()
+                       {
+                               Text = "Menu Item",
+                               Command = new Command(() =>
+                               {
+                                       throw new Exception("I shouldn't execute after removing an item");
+                               })
+                       }));
+
+                       AddContentPage(new ContentPage()
+                       {
+                               Content = new StackLayout()
+                               {
+                                       Children =
+                                       {
+                                               new Label()
+                                               {
+                                                       Text = "If you are reading this then this test has passed",
+                                                       AutomationId = "Success"
+                                               }
+                                       }
+                               }
+                       });
+                       Device.BeginInvokeOnMainThread(() =>
+                       {
+                               this.Items.Remove(item1);
+                       });
+
+               }
+
+#if UITEST
+               [Test]
+               public void RemovingShellItemCorrectlyPicksNextValidShellItemAsVisibleShellItem()
+               {
+                       RunningApp.WaitForElement("Success");
+               }
+#endif
+       }
+}
index e51a2a8..3edebfa 100644 (file)
@@ -13,6 +13,7 @@
     <Compile Include="$(MSBuildThisFileDirectory)CollectionViewHeaderFooterTemplate.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)CollectionViewHeaderFooterView.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)CollectionViewItemsUpdatingScrollMode.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Issue8008.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue6640.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue7556.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Issue7329.cs" />
index 1779780..6183d53 100644 (file)
@@ -783,7 +783,7 @@ namespace Xamarin.Forms
                {
                        base.OnChildAdded(child);
 
-                       if (child is ShellItem shellItem && CurrentItem == null && !(child is MenuShellItem))
+                       if (child is ShellItem shellItem && CurrentItem == null && ValidDefaultShellItem(child))
                        {
                                ((IShellController)this).OnFlyoutItemSelected(shellItem);
                        }
@@ -793,12 +793,22 @@ namespace Xamarin.Forms
                {
                        base.OnChildRemoved(child);
 
-                       if (child == CurrentItem && Items.Count > 0)
+                       if (child == CurrentItem)
                        {
-                               ((IShellController)this).OnFlyoutItemSelected(Items[0]);
+                               for (var i = 0; i < Items.Count; i++)
+                               {
+                                       var item = Items[i];
+                                       if (ValidDefaultShellItem(item))
+                                       {
+                                               ((IShellController)this).OnFlyoutItemSelected(item);
+                                               break;
+                                       }
+                               }
                        }
                }
 
+               bool ValidDefaultShellItem(Element child) => !(child is MenuShellItem);
+
                internal override IEnumerable<Element> ChildrenNotDrawnByThisElement
                {
                        get