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

[GH-10729] Added Current Page in Shell #10979

Merged
merged 9 commits into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions Xamarin.Forms.Core.UnitTests/ShellModalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,24 @@ public async Task NavigatingAndNavigatedFiresForShellModal()

}

[Test]
public async Task GetCurrentPageInModalNavigation()
{
Shell shell = new Shell();
shell.Items.Add(CreateShellItem(shellItemRoute: "NewRoute", shellSectionRoute: "Section", shellContentRoute: "Content"));

Page page = null;

shell.Navigated += (_, __) =>
{
page = shell.CurrentPage;
};

await shell.GoToAsync("ModalTestPage");
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
Assert.IsNotNull(page);
Assert.AreEqual(page.GetType(), typeof(ModalTestPage));
}


[QueryProperty("SomeQueryParameter", "SomeQueryParameter")]
public class ModalTestPageBase : ShellLifeCycleTests.LifeCyclePage
Expand Down
83 changes: 77 additions & 6 deletions Xamarin.Forms.Core.UnitTests/ShellTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
Expand Down Expand Up @@ -42,7 +42,7 @@ public void SetCurrentItemWithImplicitlyWrappedShellContent(bool useShellContent

BaseShellItem shellElement = null;

if(useShellContent)
if (useShellContent)
shellElement = CreateShellContent(shellContentRoute: "TestMe");
else
shellElement = CreateShellSection(shellSectionRoute: "TestMe");
Expand Down Expand Up @@ -632,7 +632,7 @@ public void CancelNavigation()

[Test]
public async Task OnBackbuttonPressedPageReturnsTrue()
{
{
TestShell shell = new TestShell();

Routing.RegisterRoute("OnBackbuttonPressedFiresOnPage", typeof(ShellTestPage));
Expand Down Expand Up @@ -1135,7 +1135,7 @@ public async Task BaseShellItemNotVisible()
public async Task CantNavigateToNotVisibleShellItem()
{
var shell = new Shell();
var item1 = CreateShellItem(shellItemRoute:"NotVisible");
var item1 = CreateShellItem(shellItemRoute: "NotVisible");
var item2 = CreateShellItem();

shell.Items.Add(item1);
Expand Down Expand Up @@ -1545,6 +1545,77 @@ public void ClearingShellSectionAndReAddingSetsCurrentItem()
}

[Test]

public async Task GetCurrentPageInShellNavigation()
{
Shell shell = new Shell();
var item1 = CreateShellItem(asImplicit: true, shellContentRoute: "rootlevelcontent1");

shell.Items.Add(item1);
Routing.RegisterRoute("cat", typeof(ContentPage));

Page page = null;

shell.Navigated += (_, __) =>
{
page = shell.CurrentPage;
};

await shell.GoToAsync("cat");
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
Assert.IsNotNull(page);
Assert.AreEqual(page.GetType(), typeof(ContentPage));
Assert.AreEqual(shell.Navigation.NavigationStack[1], page);
}

[Test]
public async Task GetCurrentPageBetweenSections()
{
var shell = new Shell();
var one = new ShellItem { Route = "one" };
var two = new ShellItem { Route = "two" };

var tabone = MakeSimpleShellSection("tabone", "content");
var tabtwo = MakeSimpleShellSection("tabtwo", "content");
var tabthree = MakeSimpleShellSection("tabthree", "content");
var tabfour = MakeSimpleShellSection("tabfour", "content");

one.Items.Add(tabone);
one.Items.Add(tabtwo);

two.Items.Add(tabthree);
two.Items.Add(tabfour);

shell.Items.Add(one);
shell.Items.Add(two);

Page page = null;

shell.Navigated += (_, __) =>
{
page = shell.CurrentPage;
};

shell.GoToAsync(new ShellNavigationState("//two/tabfour/"));
PureWeen marked this conversation as resolved.
Show resolved Hide resolved
Assert.IsNotNull(page);
Assert.AreEqual(page.GetType(), typeof(ShellTestPage));
Assert.AreEqual((tabfour as IShellSectionController).PresentedPage, page);
}

[Test]
public void GetCurrentPageOnInit()
{
var shell = new Shell();
Page page = null;
shell.Navigated += (_, __) =>
{
page = shell.CurrentPage;
};
var tabone = MakeSimpleShellSection("tabone", "content");
shell.Items.Add(tabone);
Assert.IsNotNull(page);
}


public async Task HotReloadStaysOnActiveItem()
{
Shell shell = new Shell();
Expand All @@ -1565,6 +1636,7 @@ public async Task HotReloadStaysOnActiveItem()
shell.Items.RemoveAt(0);

Assert.AreEqual("//item3", shell.CurrentState.Location.ToString());

}

[TestCase("ContentPage")]
Expand Down Expand Up @@ -1614,9 +1686,8 @@ public void SendStructureChangedFiresWhenAddingItems()
previousCount = count;
shell.CurrentItem.CurrentItem.Items.Add(CreateShellContent());
Assert.Greater(count, previousCount, "StructureChanged not fired when adding Shell Content");

}

}

//[Test]
//public void FlyoutItemLabelStyleCanBeChangedAfterRendered()
Expand Down
40 changes: 21 additions & 19 deletions Xamarin.Forms.Core/Shell/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
namespace Xamarin.Forms
{
[ContentProperty(nameof(Items))]
public class Shell : Page, IShellController, IPropertyPropagationController
public class Shell : Page, IShellController, IPropertyPropagationController, IPageContainer<Page>
{
public Page CurrentPage => (CurrentSection as IShellSectionController)?.PresentedPage;

public static readonly BindableProperty BackButtonBehaviorProperty =
BindableProperty.CreateAttached("BackButtonBehavior", typeof(BackButtonBehavior), typeof(Shell), null, BindingMode.OneTime,
propertyChanged: OnBackButonBehaviorPropertyChanged);
Expand Down Expand Up @@ -211,7 +213,7 @@ static void OnColorValueChanged(BindableObject bindable, object oldValue, object
DataTemplate IShellController.GetFlyoutItemDataTemplate(BindableObject bo)
{
BindableProperty bp = null;
string textBinding;
string textBinding;
string iconBinding;
IStyleSelectable styleClassSource = null;

Expand Down Expand Up @@ -245,7 +247,7 @@ DataTemplate IShellController.GetFlyoutItemDataTemplate(BindableObject bo)
return (DataTemplate)bo.GetValue(bp);
}

if(IsSet(bp))
if (IsSet(bp))
{
return (DataTemplate)GetValue(bp);
}
Expand Down Expand Up @@ -563,7 +565,7 @@ await Device.InvokeOnMainThreadAsync(() =>
return CurrentItem.CurrentItem.GoToAsync(navigationRequest, queryData, animate);
});
}
else if(navigationRequest.Request.GlobalRoutes.Count == 0 &&
else if (navigationRequest.Request.GlobalRoutes.Count == 0 &&
navigationRequest.StackRequest == NavigationRequest.WhatToDoWithTheStack.ReplaceIt &&
currentShellSection?.Navigation?.NavigationStack?.Count > 1)
{
Expand Down Expand Up @@ -681,21 +683,21 @@ ShellNavigationState GetNavigationState(ShellItem shellItem, ShellSection shellS
}
}

if(routeStack.Count > 0)
if (routeStack.Count > 0)
routeStack.Insert(0, "/");

return String.Join("/", routeStack);


List<string> CollapsePath(
string myRoute,
string myRoute,
List<string> currentRouteStack,
bool userDefinedRoute)
{
for (var i = currentRouteStack.Count - 1; i >= 0; i--)
{
var route = currentRouteStack[i];
if (Routing.IsImplicit(route) ||
if (Routing.IsImplicit(route) ||
(Routing.IsDefault(route) && userDefinedRoute))
currentRouteStack.RemoveAt(i);
}
Expand All @@ -705,7 +707,7 @@ List<string> CollapsePath(
// collapse similar leaves
int walkBackCurrentStackIndex = currentRouteStack.Count - (paths.Count - 1);

while(paths.Count > 1 && walkBackCurrentStackIndex >= 0)
while (paths.Count > 1 && walkBackCurrentStackIndex >= 0)
{
if (paths[0] == currentRouteStack[walkBackCurrentStackIndex])
{
Expand Down Expand Up @@ -1086,7 +1088,7 @@ async void NavigationPop()
{
await currentContent.Navigation.PopAsync();
}
catch(Exception exc)
catch (Exception exc)
{
Internals.Log.Warning(nameof(Shell), $"Failed to Navigate Back: {exc}");
}
Expand Down Expand Up @@ -1269,7 +1271,7 @@ static Dictionary<string, string> ParseQueryString(string query)
internal FlyoutBehavior GetEffectiveFlyoutBehavior()
{
ShellItem rootItem = null;
return GetEffectiveValue(Shell.FlyoutBehaviorProperty,
return GetEffectiveValue(Shell.FlyoutBehaviorProperty,
() =>
{
if (this.IsSet(FlyoutBehaviorProperty))
Expand Down Expand Up @@ -1479,14 +1481,14 @@ protected override async Task<Page> OnPopModal(bool animated)
ModalStack[ModalStack.Count - 2].SendAppearing();
}

var modalPopped = await base.OnPopModal(animated);
var modalPopped = await base.OnPopModal(animated);

if (ModalStack.Count == 0 && !_shell.CurrentItem.CurrentItem.IsPoppingModalStack)
_shell.CurrentItem.SendAppearing();

return modalPopped;
}

protected override async Task OnPushModal(Page modal, bool animated)
{
if (ModalStack.Count == 0)
Expand All @@ -1497,25 +1499,25 @@ protected override async Task OnPushModal(Page modal, bool animated)

await base.OnPushModal(modal, animated);

modal.NavigationProxy.Inner = new NavigationImplWrapper(modal.NavigationProxy.Inner, this);
modal.NavigationProxy.Inner = new NavigationImplWrapper(modal.NavigationProxy.Inner, this);
}


class NavigationImplWrapper : NavigationProxy
{
readonly INavigation _shellProxy;

public NavigationImplWrapper(INavigation proxy, INavigation shellProxy)
{
Inner = proxy;
_shellProxy = shellProxy;
_shellProxy = shellProxy;

}

protected override Task<Page> OnPopModal(bool animated) => _shellProxy.PopModalAsync(animated);

protected override Task OnPushModal(Page modal, bool animated) => _shellProxy.PushModalAsync(modal, animated);
}
}
}
}
}