Skip to content

Commit

Permalink
Set Window Parent before initialize the child ContentPage (#8653)
Browse files Browse the repository at this point in the history
* Set Window Parent before initialize the child ContentPage

* - fire appearing after parent is set on window

* Update Application.Impl.cs

* - fix up tests

* - fix application stub

* - wire up test app to test window

* - fix additional windows

Co-authored-by: Shane Neuville <[email protected]>
  • Loading branch information
jsuarezruiz and PureWeen authored Jul 19, 2022
1 parent 448dfb9 commit ca948d7
Show file tree
Hide file tree
Showing 17 changed files with 199 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ void AddWindow(Window window)

if (window is NavigableElement ne)
ne.NavigationProxy.Inner = NavigationProxy;

// Once the window has been attached to the application.
// The window will finish propagating events like `Appearing`.
//
// I could fire this from 'OnParentSet` inside Window but
// I'd rather wait until Application is done wiring itself
// up to the window before triggering any down stream life cycle
// events.
window.FinishedAddingWindowToApplication(this);
}
}
}
}
10 changes: 8 additions & 2 deletions src/Controls/src/Core/HandlerImpl/Window/Window.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,15 +264,21 @@ void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
_visualChildren.Add(item);
OnChildAdded(item);
// TODO once we have better life cycle events on pages
if (item is Page)

if (Parent != null && item is Page)
{
SendWindowAppearing();
}
}
}
}

internal void FinishedAddingWindowToApplication(Application application)
{
if (Parent != null)
SendWindowAppearing();
}

void SendWindowAppearing()
{
Page?.SendAppearing();
Expand Down
4 changes: 3 additions & 1 deletion src/Controls/src/Core/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,10 @@ public void SendAppearing()
{
// Only fire appearing if the page has been added to the windows
// Visual Hierarchy
// The window/application will take care of re-firing this appearing
// if it needs to
var window = this.FindParentOfType<Window>();
if (window == null)
if (window?.Parent == null)
{
return;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Controls/tests/Core.UnitTests/FlyoutPageUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public void ThrowsExceptionWhenAddingAlreadyParentedFlyout()
}

[Test]
public void FlyoutPageAppearingAnDisappearingPropagatesToFlyout()
public void FlyoutPageAppearingAndDisappearingPropagatesToFlyout()
{
int disappearing = 0;
int appearing = 0;
Expand All @@ -414,7 +414,7 @@ public void FlyoutPageAppearingAnDisappearingPropagatesToFlyout()
Detail = new ContentPage() { Title = "detail" }
};

_ = new Window(flyoutPage);
_ = new TestWindow(flyoutPage);
flyout.Appearing += (_, __) => appearing++;
flyout.Disappearing += (_, __) => disappearing++;

Expand All @@ -433,7 +433,7 @@ public void FlyoutPageAppearingAnDisappearingPropagatesToFlyout()
}

[Test]
public void FlyoutPageAppearingAnDisappearingPropagatesToDetail()
public void FlyoutPageAppearingAndDisappearingPropagatesToDetail()
{
int disappearing = 0;
int appearing = 0;
Expand All @@ -445,7 +445,7 @@ public void FlyoutPageAppearingAnDisappearingPropagatesToDetail()
Detail = detail
};

_ = new Window(flyoutPage);
_ = new TestWindow(flyoutPage);

detail.Appearing += (_, __) => appearing++;
detail.Disappearing += (_, __) => disappearing++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public async Task AppearingFiresForInitialPage(bool useMaui)
NavigationPage nav = new TestNavigationPage(useMaui, contentPage);

Assert.IsNull(resultPage);
_ = new Window(nav);
_ = new TestWindow(nav);
Assert.AreEqual(resultPage, contentPage);
}

Expand All @@ -44,7 +44,7 @@ public async Task PushLifeCycle(bool useMaui)
=> pageAppearing = (ContentPage)sender;

NavigationPage nav = new TestNavigationPage(useMaui, initialPage);
_ = new Window(nav);
_ = new TestWindow(nav);
nav.SendAppearing();

await nav.PushAsync(pushedPage);
Expand All @@ -64,7 +64,7 @@ public async Task PopLifeCycle(bool useMaui)
ContentPage pageDisappeared = null;

NavigationPage nav = new TestNavigationPage(useMaui, initialPage);
_ = new Window(nav);
_ = new TestWindow(nav);
nav.SendAppearing();

initialPage.Appearing += (sender, _)
Expand Down Expand Up @@ -94,7 +94,7 @@ public async Task RemoveLastPage(bool useMaui)
ContentPage pageDisappeared = null;

NavigationPage nav = new TestNavigationPage(useMaui, initialPage);
_ = new Window(nav);
_ = new TestWindow(nav);
nav.SendAppearing();

initialPage.Appearing += (sender, _)
Expand Down
14 changes: 7 additions & 7 deletions src/Controls/tests/Core.UnitTests/NavigationUnitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ public void TabBarSetsOnWindowForSingleNavigationPage()
{
var contentPage1 = new ContentPage();
var navigationPage = new TestNavigationPage(true, contentPage1);
var window = new Window(navigationPage);
var window = new TestWindow(navigationPage);

Assert.IsNotNull(window.Toolbar);
Assert.IsNull(contentPage1.Toolbar);
Expand All @@ -713,7 +713,7 @@ public void TabBarSetsOnFlyoutPage()
Flyout = new ContentPage() { Title = "Flyout" }
};

var window = new Window(flyoutPage);
var window = new TestWindow(flyoutPage);

Assert.IsNull(window.Toolbar);
Assert.IsNull(contentPage1.Toolbar);
Expand All @@ -740,7 +740,7 @@ public void TabBarSetsOnWindowWithFlyoutPageNestedInTabbedPage()
}
};

var window = new Window(tabbedPage);
var window = new TestWindow(tabbedPage);

Assert.IsNotNull(window.Toolbar);
Assert.IsNull(contentPage1.Toolbar);
Expand All @@ -752,7 +752,7 @@ public void TabBarSetsOnWindowWithFlyoutPageNestedInTabbedPage()
[Test]
public async Task TabBarSetsOnModalPageWhenWindowAlsoHasNavigationPage()
{
var window = new Window(new TestNavigationPage(true, new ContentPage()));
var window = new TestWindow(new TestNavigationPage(true, new ContentPage()));
var contentPage1 = new ContentPage();
var navigationPage = new TestNavigationPage(true, contentPage1);
await window.Navigation.PushModalAsync(navigationPage);
Expand All @@ -765,7 +765,7 @@ public async Task TabBarSetsOnModalPageWhenWindowAlsoHasNavigationPage()
[Test]
public async Task TabBarSetsOnModalPageForSingleNavigationPage()
{
var window = new Window(new ContentPage());
var window = new TestWindow(new ContentPage());
var contentPage1 = new ContentPage();
var navigationPage = new TestNavigationPage(true, contentPage1);
await window.Navigation.PushModalAsync(navigationPage);
Expand All @@ -778,7 +778,7 @@ public async Task TabBarSetsOnModalPageForSingleNavigationPage()
[Test]
public async Task TabBarSetsOnFlyoutPageInsideModalPage()
{
var window = new Window(new ContentPage());
var window = new TestWindow(new ContentPage());
var contentPage1 = new ContentPage();
var navigationPage = new TestNavigationPage(true, contentPage1);
var flyoutPage = new FlyoutPage()
Expand All @@ -799,7 +799,7 @@ public async Task TabBarSetsOnFlyoutPageInsideModalPage()
public async Task TabBarSetsOnModalPageWithFlyoutPageNestedInTabbedPage()
{
// ModalPage => TabbedPage => FlyoutPage => NavigationPage
var window = new Window(new ContentPage());
var window = new TestWindow(new ContentPage());
var contentPage1 = new ContentPage();
var navigationPage = new TestNavigationPage(true, contentPage1);
var flyoutPage = new FlyoutPage()
Expand Down
8 changes: 4 additions & 4 deletions src/Controls/tests/Core.UnitTests/PageLifeCycleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public async Task PushModalPage()
{
var previousPage = new LCPage();
var lcPage = new LCPage();
var window = new Window(previousPage);
var window = new TestWindow(previousPage);

await window.Navigation.PushModalAsync(lcPage);

Expand All @@ -141,7 +141,7 @@ public async Task PopModalPage()
var firstPage = new LCPage();
var poppedPage = new LCPage();

var window = new Window(firstPage);
var window = new TestWindow(firstPage);
await window.Navigation.PushModalAsync(poppedPage);
await window.Navigation.PopModalAsync();

Expand All @@ -161,7 +161,7 @@ public async Task PopToAModalPage()
var firstModalPage = new LCPage();
var secondModalPage = new LCPage();

var window = new Window(firstPage);
var window = new TestWindow(firstPage);
await window.Navigation.PushModalAsync(firstModalPage);
await window.Navigation.PushModalAsync(secondModalPage);

Expand All @@ -188,7 +188,7 @@ public async Task PushSecondModalPage()
var firstModalPage = new LCPage();
var secondModalPage = new LCPage();

var window = new Window(firstPage);
var window = new TestWindow(firstPage);
await window.Navigation.PushModalAsync(firstModalPage);

firstModalPage.ClearNavigationArgs();
Expand Down
16 changes: 8 additions & 8 deletions src/Controls/tests/Core.UnitTests/PageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ public void BusySentWhenBusyPageAppears()

Assert.That(sent, Is.False, "Busy message sent while not visible");

_ = new Window(page);
_ = new TestWindow(page);

Assert.That(sent, Is.True, "Busy message not sent when visible");
}
Expand All @@ -344,7 +344,7 @@ public void BusySentWhenBusyPageAppears()
public void BusySentWhenBusyPageDisappears()
{
var page = new ContentPage { IsBusy = true };
_ = new Window(page);
_ = new TestWindow(page);
((IPageController)page).SendAppearing();

var sent = false;
Expand All @@ -366,7 +366,7 @@ public void BusySentWhenVisiblePageSetToBusy()
MessagingCenter.Subscribe<Page, bool>(this, Page.BusySetSignalName, (p, b) => sent = true);

var page = new ContentPage();
_ = new Window(page);
_ = new TestWindow(page);
((IPageController)page).SendAppearing();

Assert.That(sent, Is.False, "Busy message sent appearing while not busy");
Expand Down Expand Up @@ -465,7 +465,7 @@ public void SendAppearing()
bool sent = false;
page.Appearing += (sender, args) => sent = true;

_ = new Window(page);
_ = new TestWindow(page);

Assert.True(sent);
}
Expand All @@ -474,7 +474,7 @@ public void SendAppearing()
public void SendDisappearing()
{
var page = new ContentPage();
_ = new Window(page);
_ = new TestWindow(page);

((IPageController)page).SendAppearing();

Expand All @@ -494,7 +494,7 @@ public void SendAppearingDoesntGetCalledMultipleTimes()
int countAppearing = 0;
page.Appearing += (sender, args) => countAppearing++;

_ = new Window(page);
_ = new TestWindow(page);
((IPageController)page).SendAppearing();

Assert.That(countAppearing, Is.EqualTo(1));
Expand Down Expand Up @@ -524,7 +524,7 @@ public void SendAppearingToChildrenAfter()
};
navPage.Appearing += (sender, e) => sentNav = true;

_ = new Window(navPage);
_ = new TestWindow(navPage);

Assert.True(sentNav);
Assert.True(sent);
Expand All @@ -537,7 +537,7 @@ public void SendDisappearingToChildrenPageFirst()
var page = new ContentPage();

var navPage = new NavigationPage(page);
_ = new Window(navPage);
_ = new TestWindow(navPage);
((IPageController)navPage).SendAppearing();

bool sentNav = false;
Expand Down
2 changes: 1 addition & 1 deletion src/Controls/tests/Core.UnitTests/ShellTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ public List<List<Element>> GenerateTestFlyoutItems()

public TestShell()
{
_ = new Window() { Page = this };
_ = new TestWindow() { Page = this };
Routing.RegisterRoute(nameof(TestPage1), typeof(TestPage1));
Routing.RegisterRoute(nameof(TestPage2), typeof(TestPage2));
Routing.RegisterRoute(nameof(TestPage3), typeof(TestPage3));
Expand Down
38 changes: 38 additions & 0 deletions src/Controls/tests/Core.UnitTests/TestClasses/TestApp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Maui.Controls.Core.UnitTests
{
public class TestApp : Application
{
ContentPage _withPage;
TestWindow _window;

public TestApp() : base(false)
{

}

public TestApp(TestWindow window) : base(false)
{
_window = window;
}

public TestWindow CreateWindow() =>
(TestWindow)(this as IApplication).CreateWindow(null);

protected override Window CreateWindow(IActivationState activationState)
{
return _window ?? new TestWindow(_withPage ?? new ContentPage());
}

public TestWindow CreateWindow(ContentPage withPage)
{
_withPage = withPage;
return (TestWindow)(this as IApplication).CreateWindow(null);
}
}
}
32 changes: 32 additions & 0 deletions src/Controls/tests/Core.UnitTests/TestClasses/TestWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Maui.Controls.Core.UnitTests
{
public class TestWindow : Window
{
public TestWindow()
{

}

public TestWindow(Page page) : base(page)
{
}

protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == PageProperty.PropertyName &&
Parent == null)
{
var app = new TestApp(this);
_ = (app as IApplication).CreateWindow(null);
}
}
}
}
Loading

0 comments on commit ca948d7

Please sign in to comment.