Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Shell flyout content template #13190

Merged
merged 23 commits into from
Dec 31, 2020
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<ProjectExtensions>
<VisualStudio>
<UserProperties XamarinHotReloadUnhandledDeviceExceptionXamarinFormsControlGalleryAndroidHideInfoBar="True" TriggeredFromHotReload="False" />
<UserProperties TriggeredFromHotReload="False" XamarinHotReloadUnhandledDeviceExceptionXamarinFormsControlGalleryAndroidHideInfoBar="True" />
</VisualStudio>
</ProjectExtensions>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ protected override void Init()
{
Device.InvokeOnMainThreadAsync(() =>
{
var page = AddBottomTab("Success");
page.Content = new Label() { Text = "Success" };
var page = AddBottomTab("Flyout Item");
page.Content = new Label()
{
Text = "Success"
};
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;


#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif

namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.None, 0, "Shell Flyout Content",
PlatformAffected.All)]
#if UITEST
[NUnit.Framework.Category(UITestCategories.Shell)]
[NUnit.Framework.Category(UITestCategories.UwpIgnore)]
#endif
public class ShellFlyoutContent : TestShell
{
protected override void Init()
{
var page = new ContentPage();

this.BindingContext = this;
AddFlyoutItem(page, "Flyout Item Top");
for (int i = 0; i < 50; i++)
{
AddFlyoutItem($"Flyout Item :{i}");
Items[i].AutomationId = "Flyout Item";
}

Items.Add(new MenuItem() { Text = "Menu Item" });
AddFlyoutItem("Flyout Item Bottom");

var layout = new StackLayout()
{
Children =
{
new Label()
{
Text = "Open the Flyout and Toggle the Content, Header and Footer. If it changes after each click test has passed",
AutomationId = "PageLoaded"
}
}
};

page.Content = layout;

layout.Children.Add(new Button()
{
Text = "Toggle Flyout Content Template",
Command = new Command(() =>
{
if (FlyoutContentTemplate == null)
{
FlyoutContentTemplate = new DataTemplate(() =>
{
var collectionView = new CollectionView();

collectionView.SetBinding(CollectionView.ItemsSourceProperty, "FlyoutItems");
collectionView.IsGrouped = true;

collectionView.ItemTemplate =
new DataTemplate(() =>
{
var label = new Label();

label.SetBinding(Label.TextProperty, "Title");

var button = new Button()
{
Text = "Click to Reset",
AutomationId = "ContentView",
Command = new Command(() =>
{
FlyoutContentTemplate = null;
})
};

return new StackLayout()
{
Children =
{
label,
button
}
};
});

return collectionView;
});
}
else if (FlyoutContentTemplate != null)
{
FlyoutContentTemplate = null;
}
}),
AutomationId = "ToggleFlyoutContentTemplate"
});

layout.Children.Add(new Button()
{
Text = "Toggle Flyout Content",
Command = new Command(() =>
{
if (FlyoutContent != null)
{
FlyoutContent = null;
}
else
{
var stackLayout = new StackLayout()
{
Background = SolidColorBrush.Green
};

FlyoutContent = new ScrollView()
{
Content = stackLayout
};

AddButton("Top Button");

for (int i = 0; i < 50; i++)
{
AddButton("Content View");
}

AddButton("Bottom Button");

void AddButton(string text)
{
stackLayout.Children.Add(new Button()
{
Text = text,
AutomationId = "ContentView",
Command = new Command(() =>
{
FlyoutContent = null;
}),
TextColor = Color.White
});
}
}
}),
AutomationId = "ToggleContent"
});

layout.Children.Add(new Button()
{
Text = "Toggle Header/Footer View",
Command = new Command(() =>
{
if (FlyoutHeader != null)
{
FlyoutHeader = null;
FlyoutFooter = null;
}
else
{
FlyoutHeader = new StackLayout()
{
Children = {
new Label() { Text = "Header" }
},
AutomationId = "Header View",
Background = SolidColorBrush.Yellow
};

FlyoutFooter = new StackLayout()
{
Background = SolidColorBrush.Orange,
Orientation = StackOrientation.Horizontal,
Children = {
new Label() { Text = "Footer" }
},
AutomationId = "Footer View"
};
}
}),
AutomationId = "ToggleHeaderFooter"
});
}


#if UITEST

[Test]
public void FlyoutContentTests()
{
RunningApp.WaitForElement("PageLoaded");
TapInFlyout("Flyout Item");
RunningApp.Tap("ToggleContent");
TapInFlyout("ContentView");
TapInFlyout("Flyout Item");
RunningApp.Tap("ToggleFlyoutContentTemplate");
TapInFlyout("ContentView");
TapInFlyout("Flyout Item");
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ public ContentPage AddBottomTab(string title, string icon = null)
ContentPage page = new ContentPage();
if (Items.Count == 0)
{
var item = AddContentPage(page);
var item = AddContentPage(page, title);
item.Items[0].Items[0].Title = title ?? page.Title;
item.Items[0].Title = title ?? page.Title;
return page;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewGroupTypeIssue.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue11214.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue13109.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ShellFlyoutContent.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue4720.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue10897.xaml.cs">
<DependentUpon>Issue10897.xaml</DependentUpon>
Expand Down
87 changes: 84 additions & 3 deletions Xamarin.Forms.Core.UnitTests/ShellFlyoutItemGroupTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ public void FlyoutItemVisibleWorksForMenuItemsFlyoutItemAsMultipleItems()
flyoutItem.CurrentItem.CurrentItem.MenuItems.Add(CreateNonVisibleMenuItem());
shell.Items.Add(flyoutItem);


IShellController shellController = (IShellController)shell;
var groups = shellController.GenerateFlyoutGrouping();
var groups = shell.Controller.GenerateFlyoutGrouping();
Assert.AreEqual(groups.SelectMany(x => x.OfType<IMenuItemController>()).Count(), 0);
}

Expand Down Expand Up @@ -221,6 +219,89 @@ public void ReturnTheSameGroupingInstanceIfStructureHasntChanged()
Assert.AreNotSame(flyoutItems, flyoutItems2);
}

[Test]
public void FlyoutItemsBasicSyncTest()
{
var shell = new TestShell();
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items[3].IsVisible = false;

var flyoutItems = shell.GenerateTestFlyoutItems();
Assert.AreEqual(shell.Items[0], flyoutItems[0][0]);
Assert.AreEqual(shell.Items[1], flyoutItems[0][1]);
Assert.AreEqual(shell.Items[2], flyoutItems[0][2]);
Assert.AreEqual(3, flyoutItems[0].Count);
Assert.AreEqual(1, flyoutItems.Count);
}

[Test]
public void FlyoutItemsGroupTest()
{
var shell = new TestShell();
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items.Add(CreateShellItem<FlyoutItem>());
var sec1 = shell.Items[0].Items[0];
var sec2 = CreateShellSection<Tab>();
var sec3 = CreateShellSection<Tab>();

shell.Items[0].FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems;
shell.Items[0].Items.Add(sec2);
shell.Items[0].Items.Add(sec3);

var flyoutItems = shell.GenerateTestFlyoutItems();
Assert.AreEqual(sec1, flyoutItems[0][0]);
Assert.AreEqual(sec2, flyoutItems[0][1]);
Assert.AreEqual(sec3, flyoutItems[0][2]);
Assert.AreEqual(shell.Items[1], flyoutItems[1][0]);
}

[Test]
public void FlyoutItemsGroupTestWithRemove()
{
var shell = new TestShell();
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items.Add(CreateShellItem<FlyoutItem>());
var sec1 = shell.Items[0].Items[0];
var sec2 = CreateShellSection<Tab>();
var sec3 = CreateShellSection<Tab>();

shell.Items[0].FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems;
shell.Items[0].Items.Add(sec2);
shell.Items[0].Items.Add(sec3);
shell.Items.RemoveAt(0);

var flyoutItems = shell.GenerateTestFlyoutItems();
Assert.AreEqual(shell.Items[0], flyoutItems[0][0]);
Assert.AreEqual(1, flyoutItems.Count);
}

[Test]
public void FlyoutItemsGroupTestMoveGroup()
{
var shell = new TestShell();
shell.Items.Add(CreateShellItem<FlyoutItem>());
shell.Items.Add(CreateShellItem<FlyoutItem>());
var sec1 = shell.Items[0].Items[0];
var sec2 = CreateShellSection<Tab>();
var sec3 = CreateShellSection<Tab>();

shell.Items[0].FlyoutDisplayOptions = FlyoutDisplayOptions.AsMultipleItems;
shell.Items[0].Items.Add(sec2);
shell.Items[0].Items.Add(sec3);

var item1 = shell.Items[0];
shell.Items.RemoveAt(0);
shell.Items.Add(item1);
var flyoutItems = shell.GenerateTestFlyoutItems();
Assert.AreEqual(sec1, flyoutItems[1][0]);
Assert.AreEqual(sec2, flyoutItems[1][1]);
Assert.AreEqual(sec3, flyoutItems[1][2]);
Assert.AreEqual(shell.Items[0], flyoutItems[0][0]);
}

MenuItem CreateNonVisibleMenuItem()
{
MenuItem item = new MenuItem();
Expand Down
13 changes: 13 additions & 0 deletions Xamarin.Forms.Core.UnitTests/ShellTestBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
Expand Down Expand Up @@ -300,6 +301,18 @@ public class TestShell : Shell

public IShellController Controller => this;

public List<List<Element>> GenerateTestFlyoutItems()
{
List<List<Element>> returnValue = new List<List<Element>>();


FlyoutItems
.OfType<IEnumerable>()
.ForEach(l => returnValue.Add(l.OfType<Element>().ToList()));

return returnValue;
}

public TestShell()
{
this.Navigated += (_, __) => NavigatedCount++;
Expand Down
1 change: 0 additions & 1 deletion Xamarin.Forms.Core/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ internal override IEnumerable<Element> ChildrenNotDrawnByThisElement

if (titleViewPart2TheNavBar != null)
yield return titleViewPart2TheNavBar;

}
}

Expand Down
2 changes: 2 additions & 0 deletions Xamarin.Forms.Core/Shell/IShellController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public interface IShellController : IPageController

View FlyoutFooter { get; }

View FlyoutContent { get; }

ImageSource FlyoutIcon { get; }

void AddAppearanceObserver(IAppearanceObserver observer, Element pivot);
Expand Down