Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b1155de
Added repro sample
jsuarezruiz Mar 12, 2025
3aa95d5
Added UITests
jsuarezruiz Mar 12, 2025
c54d712
Changes in navigation events parameters
jsuarezruiz Mar 12, 2025
1143890
Fix failing UITest
jsuarezruiz Mar 13, 2025
d4a48e1
Fixed test
jsuarezruiz Mar 18, 2025
3f97a13
Fixed test on iOS/Catalyst
jsuarezruiz May 22, 2025
55e4987
Renamed NavigationType.PageSwap to NavigationType.Replace
jsuarezruiz Jun 5, 2025
a612fdb
Removed NavigationType.Initialized
jsuarezruiz Jun 5, 2025
8624cb1
Added two more samples, using tabs and flyout
jsuarezruiz Jun 5, 2025
a22156c
Updated sample
jsuarezruiz Jun 5, 2025
be30c11
Create Issue21814TabbedPage.cs
jsuarezruiz Jun 5, 2025
bcdcff7
Updated flyout sample
jsuarezruiz Jun 5, 2025
f543582
Adding more tests
jsuarezruiz Jun 5, 2025
3d3dd2a
Added more TabbedPage tests
jsuarezruiz Jun 6, 2025
4ae778a
More FlyoutPage tests
jsuarezruiz Jun 6, 2025
8dfba1d
Updated test
jsuarezruiz Jun 6, 2025
c45bf21
Fixed tests
jsuarezruiz Jun 17, 2025
20b8f52
Use Replace with Tabs and FlyoutItems
jsuarezruiz Jun 26, 2025
c9c1a4e
Fixed unit tests
jsuarezruiz Jun 27, 2025
2b3cc79
Updated test
jsuarezruiz Jun 27, 2025
1223371
Fix iOS Flyout tests
jsuarezruiz Jun 30, 2025
631300c
Changes in tests
jsuarezruiz Jun 30, 2025
207e075
Fix test on Android
jsuarezruiz Jul 2, 2025
435fe31
Fixed Windows test
jsuarezruiz Jul 3, 2025
a5f5774
Fixed parameters in NavigatingFromEventArgs
jsuarezruiz Jul 14, 2025
882f728
Updated TabbedPage unit test
jsuarezruiz Jul 15, 2025
97e282c
Added more navigation unit tests
jsuarezruiz Jul 15, 2025
6442596
- fix publicapi.txt files
PureWeen Jul 24, 2025
5cde60c
Update FlyoutPage.cs
PureWeen Jul 24, 2025
a143401
Update FlyoutPage.cs
PureWeen Jul 24, 2025
f6f4e70
Update MultiPage.cs
PureWeen Jul 24, 2025
78cd921
- fix publicapi
PureWeen Jul 28, 2025
a21aa12
More tests
jsuarezruiz Jul 29, 2025
ed9319a
Fixed device test
jsuarezruiz Jul 29, 2025
97efcee
Changes based on PR feedback, simplify FlyoutPage Detail
jsuarezruiz Jul 30, 2025
98bb1cf
More changes to fix a test
jsuarezruiz Jul 30, 2025
4ad8eae
[ci] Update the publicapi
rmarinho Jul 31, 2025
c809393
- remove navigatingfrom
PureWeen Aug 1, 2025
ddc4874
Updated tests
jsuarezruiz Aug 1, 2025
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
41 changes: 31 additions & 10 deletions src/Controls/src/Core/FlyoutPage/FlyoutPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,44 @@ public Page Detail
throw new InvalidOperationException("Detail must not already have a parent.");

var previousDetail = _detail;
// TODO MAUI refine this to fire earlier
_detail?.SendNavigatingFrom(new NavigatingFromEventArgs());

// Get the actual pages for navigation events (unwrap NavigationPages)
var destinationPage =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value is NavigationPage destinationNavPage ? destinationNavPage.CurrentPage : value;
var previousPage = previousDetail is NavigationPage previousNavPage
? previousNavPage.CurrentPage
: previousDetail;

// Send NavigatingFrom event to the previous detail (if any)
if (previousDetail is not null)
{
previousDetail.SendNavigatingFrom(new NavigatingFromEventArgs(destinationPage,
NavigationType.Replace));
}

// Update the detail property
OnPropertyChanging();
if (_detail != null)
if (_detail is not null)
InternalChildren.Remove(_detail);
_detail = value;
InternalChildren.Add(_detail);
OnPropertyChanged();

if (this.HasAppeared)
// Handle Appearing/Disappearing events if the FlyoutPage has appeared
if (HasAppeared)
{
previousDetail?.SendDisappearing();
_detail?.SendAppearing();
}

previousDetail?.SendNavigatedFrom(new NavigatedFromEventArgs(_detail, NavigationType.PageSwap));
_detail?.SendNavigatedTo(new NavigatedToEventArgs(previousDetail));
// Send NavigatedFrom and NavigatedTo events
if (previousDetail is not null)
{
previousDetail.SendNavigatedFrom(
new NavigatedFromEventArgs(destinationPage, NavigationType.Replace));
}

_detail.SendNavigatedTo(new NavigatedToEventArgs(previousPage, NavigationType.Replace));
}
}

Expand Down Expand Up @@ -108,8 +128,9 @@ public Page Flyout

// TODO MAUI refine this to fire earlier
var previousFlyout = _flyout;

// TODO MAUI refine this to fire earlier
_flyout?.SendNavigatingFrom(new NavigatingFromEventArgs());
previousFlyout?.SendNavigatingFrom(new NavigatingFromEventArgs(value, NavigationType.Replace));

OnPropertyChanging();
if (_flyout != null)
Expand All @@ -123,9 +144,9 @@ public Page Flyout
previousFlyout?.SendDisappearing();
_flyout?.SendAppearing();
}

previousFlyout?.SendNavigatedFrom(new NavigatedFromEventArgs(_flyout, NavigationType.PageSwap));
_flyout?.SendNavigatedTo(new NavigatedToEventArgs(previousFlyout));
previousFlyout?.SendNavigatedFrom(new NavigatedFromEventArgs(_flyout, NavigationType.Replace));
_flyout?.SendNavigatedTo(new NavigatedToEventArgs(previousFlyout, NavigationType.Replace));
}
}

Expand Down
20 changes: 13 additions & 7 deletions src/Controls/src/Core/MultiPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,15 @@ public T CurrentPage

var previousPage = _current;
OnPropertyChanging();

// TODO: MAUI refine this to fire earlier
_current?.SendNavigatingFrom(new NavigatingFromEventArgs());


// Send NavigatingFrom to the previous page or to the new page if no previous page exists
if (_current is not null)
{
_current.SendNavigatingFrom(new NavigatingFromEventArgs(value, NavigationType.Replace));
}

_current = value;

previousPage?.SendDisappearing();
Expand All @@ -96,9 +101,10 @@ public T CurrentPage

if (HasAppeared)
_current?.SendAppearing();

previousPage?.SendNavigatedFrom(new NavigatedFromEventArgs(_current, NavigationType.PageSwap));
_current?.SendNavigatedTo(new NavigatedToEventArgs(previousPage));


previousPage?.SendNavigatedFrom(new NavigatedFromEventArgs(_current, NavigationType.Replace));
_current?.SendNavigatedTo(new NavigatedToEventArgs(previousPage, NavigationType.Replace));
}
}

Expand Down Expand Up @@ -377,4 +383,4 @@ void UpdateCurrentPage()
CurrentPage = (T)SelectedItem;
}
}
}
}
4 changes: 2 additions & 2 deletions src/Controls/src/Core/NavigationModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public Page PopModal()
_navTree[0].Count > 0 &&
_navTree[0][0] is not Shell)
{
previousPage.SendNavigatingFrom(new NavigatingFromEventArgs());
previousPage.SendNavigatingFrom(new NavigatingFromEventArgs(CurrentPage, NavigationType.Pop));
previousPage.SendDisappearing();
CurrentPage.SendAppearing();
}
Expand Down Expand Up @@ -201,7 +201,7 @@ public void PushModal(Page page)
_navTree[0].Count > 0 &&
_navTree[0][0] is not Shell)
{
previousPage.SendNavigatingFrom(new NavigatingFromEventArgs());
previousPage.SendNavigatingFrom(new NavigatingFromEventArgs(page, NavigationType.Push));
previousPage.SendDisappearing();
page.SendAppearing();
}
Expand Down
14 changes: 8 additions & 6 deletions src/Controls/src/Core/NavigationPage/NavigationPage.Legacy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async Task<Page> PopAsyncInner(

var page = (Page)InternalChildren.Last();
var previousPage = CurrentPage;
SendNavigating();
SendNavigating(NavigationType.Pop, previousPage);
var removedPage = await RemoveAsyncInner(page, animated, fast);
SendNavigated(previousPage, NavigationType.Pop);
return removedPage;
Expand Down Expand Up @@ -150,7 +150,7 @@ async Task PopToRootAsyncInner(bool animated)
return;

var previousPage = CurrentPage;
SendNavigating();
SendNavigating(NavigationType.PopToRoot, previousPage);
FireDisappearing(CurrentPage);
FireAppearing((Page)InternalChildren[0]);

Expand Down Expand Up @@ -183,7 +183,9 @@ async Task PushAsyncInner(Page page, bool animated)
return;

var previousPage = CurrentPage;
SendNavigating();
var navigationType = DetermineNavigationType();

SendNavigating(navigationType, previousPage);
FireDisappearing(CurrentPage);
FireAppearing(page);

Expand All @@ -198,9 +200,9 @@ async Task PushAsyncInner(Page page, bool animated)

if (args.Task != null)
await args.Task;
}

SendNavigated(previousPage, NavigationType.Push);
}
SendNavigated(previousPage, navigationType);
Pushed?.Invoke(this, args);
}

Expand Down
45 changes: 35 additions & 10 deletions src/Controls/src/Core/NavigationPage/NavigationPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public partial class NavigationPage : Page, IPageContainer<Page>, IBarElement, I

INavigationPageController NavigationPageController => this;


partial void Init();

#if WINDOWS || ANDROID || TIZEN
Expand All @@ -63,6 +64,7 @@ public partial class NavigationPage : Page, IPageContainer<Page>, IBarElement, I
#endif

bool _setForMaui;

/// <include file="../../docs/Microsoft.Maui.Controls/NavigationPage.xml" path="//Member[@MemberName='.ctor'][1]/Docs/*" />
public NavigationPage() : this(UseMauiHandler)
{
Expand Down Expand Up @@ -112,6 +114,8 @@ public Color BarTextColor

internal Task CurrentNavigationTask { get; set; }

internal NavigationType NavigationType { get; set; }

/// <include file="../../docs/Microsoft.Maui.Controls/NavigationPage.xml" path="//Member[@MemberName='Peek']/Docs/*" />
[EditorBrowsable(EditorBrowsableState.Never)]
public Page Peek(int depth)
Expand Down Expand Up @@ -377,12 +381,12 @@ protected override bool OnBackButtonPressed()
void SendNavigated(Page previousPage, NavigationType navigationType)
{
previousPage?.SendNavigatedFrom(new NavigatedFromEventArgs(CurrentPage, navigationType));
CurrentPage.SendNavigatedTo(new NavigatedToEventArgs(previousPage));
CurrentPage.SendNavigatedTo(new NavigatedToEventArgs(previousPage, navigationType));
}

void SendNavigating(Page navigatingFrom = null)
void SendNavigating(NavigationType navigationType, Page navigatingFrom = null)
{
(navigatingFrom ?? CurrentPage)?.SendNavigatingFrom(new NavigatingFromEventArgs());
(navigatingFrom ?? CurrentPage)?.SendNavigatingFrom(new NavigatingFromEventArgs(CurrentPage, navigationType));
}


Expand Down Expand Up @@ -691,16 +695,17 @@ private protected override void OnHandlerChangedCore()
var visiblePage = Navigation.NavigationStack[NavigationStack.Count - 1];
RootPage = navStack[0];
CurrentPage = visiblePage;


var navigationType = DetermineNavigationType();

SendHandlerUpdateAsync(false, null,
() =>
{
FireAppearing(CurrentPage);
},
() =>
{
// TODO this is the wrong navigation type
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was passing the wrong navigation type parameter. If we not decide to update the navigation EventArgs with the properties included in this PR, the changes to fix this should be included in another one.

SendNavigated(null, NavigationType.Initialize);
SendNavigated(null, navigationType);
})
.FireAndForget(Handler);
}
Expand All @@ -712,7 +717,21 @@ private protected override void OnHandlerChangedCore()
((IStackNavigation)this).NavigationFinished(this.NavigationStack);
}
}

NavigationType DetermineNavigationType()
{
var parentPages = this.GetParentPages();

bool hasTabOrFlyout = parentPages.Any(page => page is FlyoutPage or TabbedPage);

if (hasTabOrFlyout)
{
return NavigationType.Replace;
}

return NavigationType.Push;
}

// Once we get all platforms over to the new APIs
// we can just delete all the code inside NavigationPage.cs that fires "requested" events
class MauiNavigationImpl : NavigationProxy
Expand Down Expand Up @@ -750,6 +769,7 @@ protected override void OnInsertPageBefore(Page page, Page before)
Owner.SendHandlerUpdateAsync(false,
() =>
{
Owner.NavigationType = NavigationType.Insert;
int index = Owner.InternalChildren.IndexOf(before);
Owner.InternalChildren.Insert(index, page);

Expand Down Expand Up @@ -783,6 +803,7 @@ protected async override Task<Page> OnPopAsync(bool animated)
await Owner.SendHandlerUpdateAsync(animated,
() =>
{
Owner.NavigationType = NavigationType.Pop;
Owner.CurrentPage = newCurrentPage;
Owner.RemoveFromInnerChildren(currentPage);
if (currentPage.TitleView != null)
Expand All @@ -792,7 +813,7 @@ await Owner.SendHandlerUpdateAsync(animated,
},
() =>
{
Owner.SendNavigating(currentPage);
Owner.SendNavigating(NavigationType.Pop, currentPage);
Owner.FireDisappearing(currentPage);
Owner.FireAppearing(newCurrentPage);
},
Expand All @@ -817,6 +838,7 @@ protected override Task OnPopToRootAsync(bool animated)
return Owner.SendHandlerUpdateAsync(animated,
() =>
{
Owner.NavigationType = NavigationType.PopToRoot;
var lastIndex = NavigationStack.Count - 1;
while (lastIndex > 0)
{
Expand All @@ -829,7 +851,7 @@ protected override Task OnPopToRootAsync(bool animated)
},
() =>
{
Owner.SendNavigating(previousPage);
Owner.SendNavigating(NavigationType.PopToRoot, previousPage);
Owner.FireDisappearing(previousPage);
Owner.FireAppearing(newPage);
},
Expand All @@ -845,22 +867,24 @@ protected override Task OnPushAsync(Page root, bool animated)
if (Owner.InternalChildren.Contains(root))
return Task.CompletedTask;

var navigationType = Owner.DetermineNavigationType();
var previousPage = Owner.CurrentPage;

return Owner.SendHandlerUpdateAsync(animated,
() =>
{
Owner.NavigationType = navigationType;
Owner.PushPage(root);
},
() =>
{
Owner.SendNavigating(previousPage);
Owner.SendNavigating(navigationType, previousPage);
Owner.FireDisappearing(previousPage);
Owner.FireAppearing(root);
},
() =>
{
Owner.SendNavigated(previousPage, NavigationType.Push);
Owner.SendNavigated(previousPage, navigationType);
Owner?.Pushed?.Invoke(Owner, new NavigationEventArgs(root));
});
}
Expand All @@ -886,6 +910,7 @@ protected override void OnRemovePage(Page page)
Owner.SendHandlerUpdateAsync(false,
() =>
{
Owner.NavigationType = NavigationType.Remove;
Owner.RemoveFromInnerChildren(page);

if (Owner.RootPage == page)
Expand Down
18 changes: 3 additions & 15 deletions src/Controls/src/Core/Page/NavigatedFromEventArgs.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
#nullable disable
using System;
using Microsoft.Maui.Controls.Internals;

namespace Microsoft.Maui.Controls
{
internal enum NavigationType
{
Push,
Pop,
PopToRoot,
Insert,
Remove,
PageSwap,
Initialize
}

public sealed class NavigatedFromEventArgs : EventArgs
{
internal NavigationType NavigationType { get; }
public NavigationType NavigationType { get; }

internal Page DestinationPage { get; }
public Page DestinationPage { get; }

internal NavigatedFromEventArgs(Page destinationPage, NavigationType navigationType)
{
DestinationPage = destinationPage;
NavigationType = navigationType;
}
}
}
}
6 changes: 4 additions & 2 deletions src/Controls/src/Core/Page/NavigatedToEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ namespace Microsoft.Maui.Controls
{
public sealed class NavigatedToEventArgs : EventArgs
{
internal NavigatedToEventArgs(Page previousPage)
internal NavigatedToEventArgs(Page previousPage, NavigationType navigationType)
{
PreviousPage = previousPage;
NavigationType = navigationType;
}

internal Page PreviousPage { get; }
public Page PreviousPage { get; }
public NavigationType NavigationType { get; }
}
}
Loading
Loading