Route Navigation.(Push/Pop)Modal through Shell Navigation Manager (#14080)
* Route Navigation.(Push/Pop)Modal through Shell Navigation Mananger * - fix SO error * Update ShellNavigationManager.cs
This commit is contained in:
Родитель
89ea384f12
Коммит
46d1d9dd1a
|
@ -381,6 +381,55 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
Assert.AreEqual(page.GetType(), typeof(ModalTestPage));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PopModalWithDots()
|
||||
{
|
||||
Shell shell = new Shell();
|
||||
shell.Items.Add(CreateShellItem());
|
||||
|
||||
await shell.CurrentPage.Navigation.PushModalAsync(new ContentPage());
|
||||
await shell.CurrentPage.Navigation.PushModalAsync(new ContentPage());
|
||||
await shell.GoToAsync("..");
|
||||
Assert.AreEqual(1, shell.Navigation.ModalStack.Count);
|
||||
await shell.GoToAsync("..");
|
||||
Assert.AreEqual(0, shell.Navigation.ModalStack.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CanCancelGoToModalAsync()
|
||||
{
|
||||
TestShell shell = new TestShell();
|
||||
shell.Items.Add(CreateShellItem());
|
||||
|
||||
shell.Navigating += async (_, args) =>
|
||||
{
|
||||
var deferral = args.GetDeferral();
|
||||
await Task.Delay(10);
|
||||
args.Cancel();
|
||||
deferral.Complete();
|
||||
};
|
||||
|
||||
await shell.GoToAsync("ModalTestPage");
|
||||
Assert.AreEqual(0, shell.Navigation.ModalStack.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task CanCancelPushModalAsync()
|
||||
{
|
||||
TestShell shell = new TestShell();
|
||||
|
||||
shell.Items.Add(CreateShellItem());
|
||||
shell.Navigating += async (_, args) =>
|
||||
{
|
||||
var deferral = args.GetDeferral();
|
||||
await Task.Delay(10);
|
||||
args.Cancel();
|
||||
deferral.Complete();
|
||||
};
|
||||
|
||||
await shell.CurrentPage.Navigation.PushModalAsync(new ContentPage());
|
||||
Assert.AreEqual(0, shell.Navigation.ModalStack.Count);
|
||||
}
|
||||
|
||||
[QueryProperty("SomeQueryParameter", "SomeQueryParameter")]
|
||||
public class ModalTestPageBase : ShellLifeCycleTests.LifeCyclePage
|
||||
|
|
|
@ -889,14 +889,14 @@ namespace Xamarin.Forms.Core.UnitTests
|
|||
public class NavigationImpl : NavigationProxy
|
||||
{
|
||||
readonly NavigationMonitoringTab _navigationMonitoringTab;
|
||||
readonly INavigation _navigation;
|
||||
readonly NavigationProxy _navigation;
|
||||
|
||||
public NavigationImpl(
|
||||
NavigationMonitoringTab navigationMonitoringTab,
|
||||
INavigation navigation)
|
||||
{
|
||||
_navigationMonitoringTab = navigationMonitoringTab;
|
||||
_navigation = navigation;
|
||||
_navigation = (NavigationProxy)navigation;
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<Page> GetModalStack() => _navigation.ModalStack;
|
||||
|
|
|
@ -105,6 +105,7 @@ namespace Xamarin.Forms
|
|||
|
||||
internal static void Clear()
|
||||
{
|
||||
s_implicitPageRoutes.Clear();
|
||||
s_routes.Clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace Xamarin.Forms
|
|||
|
||||
bool AddNode(BaseShellItem baseShellItem, string nextSegment)
|
||||
{
|
||||
_ = baseShellItem ?? throw new ArgumentNullException(nameof(baseShellItem));
|
||||
|
||||
if (Routing.IsUserDefined(baseShellItem.Route) && baseShellItem.Route != nextSegment)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace Xamarin.Forms
|
|||
|
||||
public void HandleNavigated(ShellNavigatedEventArgs args)
|
||||
{
|
||||
if (_accumulateNavigatedEvents)
|
||||
if (AccumulateNavigatedEvents)
|
||||
{
|
||||
if (_accumulatedEvent == null)
|
||||
_accumulatedEvent = args;
|
||||
|
@ -286,7 +286,7 @@ namespace Xamarin.Forms
|
|||
bool canCancel,
|
||||
bool isAnimated)
|
||||
{
|
||||
if (_accumulateNavigatedEvents)
|
||||
if (AccumulateNavigatedEvents)
|
||||
return true;
|
||||
|
||||
var proposedState = GetNavigationState(shellItem, shellSection, shellContent, stack, shellSection.Navigation.ModalStack);
|
||||
|
@ -319,7 +319,7 @@ namespace Xamarin.Forms
|
|||
bool canCancel,
|
||||
bool isAnimated)
|
||||
{
|
||||
if (_accumulateNavigatedEvents)
|
||||
if (AccumulateNavigatedEvents)
|
||||
return null;
|
||||
|
||||
var navArgs = new ShellNavigatingEventArgs(_shell.CurrentState, proposedState, source, canCancel)
|
||||
|
|
|
@ -354,7 +354,7 @@ namespace Xamarin.Forms
|
|||
var page = GetOrCreateFromRoute(globalRoutes[i], queryData, i == globalRoutes.Count - 1, false);
|
||||
if (IsModal(page))
|
||||
{
|
||||
await Navigation.PushModalAsync(page, IsNavigationAnimated(page));
|
||||
await PushModalAsync(page, IsNavigationAnimated(page));
|
||||
break;
|
||||
}
|
||||
else if (!isLast && navIndex < _navStack.Count)
|
||||
|
@ -409,7 +409,7 @@ namespace Xamarin.Forms
|
|||
bool isAnimated = animate ?? IsNavigationAnimated(navStack[navStack.Count - 1]);
|
||||
if (Navigation.ModalStack.Contains(navStack[navStack.Count - 1]))
|
||||
{
|
||||
await Navigation.PopModalAsync(isAnimated);
|
||||
await PopModalAsync(isAnimated);
|
||||
}
|
||||
else if (Navigation.ModalStack.Count > 0)
|
||||
{
|
||||
|
@ -550,7 +550,7 @@ namespace Xamarin.Forms
|
|||
|
||||
if (modalPage is NavigationPage np)
|
||||
{
|
||||
await Navigation.PushModalAsync(modalPage, isAnimated);
|
||||
await PushModalAsync(modalPage, isAnimated);
|
||||
activeModalNavigationPage = np;
|
||||
}
|
||||
else
|
||||
|
@ -558,7 +558,7 @@ namespace Xamarin.Forms
|
|||
if (activeModalNavigationPage != null)
|
||||
await activeModalNavigationPage.Navigation.PushAsync(modalPage, animate ?? IsNavigationAnimated(modalPage));
|
||||
else
|
||||
await Navigation.PushModalAsync(modalPage, isAnimated);
|
||||
await PushModalAsync(modalPage, isAnimated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,6 +570,22 @@ namespace Xamarin.Forms
|
|||
}
|
||||
}
|
||||
|
||||
Task PopModalAsync(bool isAnimated)
|
||||
{
|
||||
if (Navigation is NavigationImpl shellSectionProxy)
|
||||
return shellSectionProxy.PopModalInnerAsync(isAnimated);
|
||||
|
||||
return Navigation.PopModalAsync(isAnimated);
|
||||
}
|
||||
|
||||
Task PushModalAsync(Page page, bool isAnimated)
|
||||
{
|
||||
if (Navigation is NavigationImpl shellSectionProxy)
|
||||
return shellSectionProxy.PushModalInnerAsync(page, isAnimated);
|
||||
|
||||
return Navigation.PushModalAsync(page, isAnimated);
|
||||
}
|
||||
|
||||
async Task PushStackOfPages(List<Page> pages, bool? animate)
|
||||
{
|
||||
for (int i = pages.Count - 1; i >= 0; i--)
|
||||
|
@ -852,7 +868,7 @@ namespace Xamarin.Forms
|
|||
}
|
||||
|
||||
bool isAnimated = animated ?? (Shell.GetPresentationMode(pageToPop) & PresentationMode.NotAnimated) != PresentationMode.NotAnimated;
|
||||
await Navigation.PopModalAsync(isAnimated);
|
||||
await PopModalAsync(isAnimated);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@ -1089,6 +1105,52 @@ namespace Xamarin.Forms
|
|||
return _owner.Shell.NavigationManager.GoToAsync(navigationParameters);
|
||||
}
|
||||
|
||||
// This is used when we just want to process the modal operation and we don't need
|
||||
// it to process through the internal shell navigation bits
|
||||
internal Task PushModalInnerAsync(Page modal, bool animated)
|
||||
{
|
||||
return Inner?.PushModalAsync(modal, animated);
|
||||
}
|
||||
|
||||
// This is used when we just want to process the modal operation and we don't need
|
||||
// it to process through the internal shell navigation bits
|
||||
internal Task<Page> PopModalInnerAsync(bool animated)
|
||||
{
|
||||
return Inner?.PopModalAsync(animated);
|
||||
}
|
||||
|
||||
protected override async Task OnPushModal(Page modal, bool animated)
|
||||
{
|
||||
if (_owner.Shell.NavigationManager.AccumulateNavigatedEvents)
|
||||
{
|
||||
await base.OnPushModal(modal, animated);
|
||||
return;
|
||||
}
|
||||
|
||||
if (animated)
|
||||
Shell.SetPresentationMode(modal, PresentationMode.ModalAnimated);
|
||||
else
|
||||
Shell.SetPresentationMode(modal, PresentationMode.ModalNotAnimated);
|
||||
|
||||
var navigationParameters = new ShellNavigationParameters()
|
||||
{
|
||||
Animated = animated,
|
||||
PagePushing = modal
|
||||
};
|
||||
|
||||
await _owner.Shell.NavigationManager.GoToAsync(navigationParameters);
|
||||
}
|
||||
|
||||
protected async override Task<Page> OnPopModal(bool animated)
|
||||
{
|
||||
if (_owner.Shell.NavigationManager.AccumulateNavigatedEvents)
|
||||
return await base.OnPopModal(animated);
|
||||
|
||||
var page = ModalStack[ModalStack.Count - 1];
|
||||
await _owner.Shell.GoToAsync("..", animated);
|
||||
return page;
|
||||
}
|
||||
|
||||
protected override void OnRemovePage(Page page)
|
||||
{
|
||||
if (!_owner.IsVisibleSection || _owner.Shell.NavigationManager.AccumulateNavigatedEvents)
|
||||
|
@ -1149,4 +1211,4 @@ namespace Xamarin.Forms
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -284,12 +284,16 @@ namespace Xamarin.Forms
|
|||
continue;
|
||||
|
||||
var url = possibleRoutePath.PathFull;
|
||||
var currentLocation = possibleRoutePath.GetNodeLocation();
|
||||
|
||||
if (currentLocation.Content == null)
|
||||
continue;
|
||||
|
||||
var globalRouteMatches =
|
||||
SearchForGlobalRoutes(
|
||||
possibleRoutePath.RemainingSegments,
|
||||
new ShellNavigationState(url, false).FullLocation,
|
||||
possibleRoutePath.GetNodeLocation(),
|
||||
currentLocation,
|
||||
routeKeys);
|
||||
|
||||
if (globalRouteMatches.Count != 1)
|
||||
|
|
Загрузка…
Ссылка в новой задаче