Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix window events when swapping out a page #11483

Merged
merged 1 commit into from
Nov 18, 2022
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
51 changes: 23 additions & 28 deletions src/Controls/src/Core/HandlerImpl/Window/Window.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public partial class Window : NavigableElement, IWindow, IVisualTreeElement, ITo
public static readonly BindableProperty PageProperty = BindableProperty.Create(
nameof(Page), typeof(Page), typeof(Window), default(Page?),
propertyChanging: OnPageChanging,
propertyChanged: OnPageChanged);
propertyChanged: (b, o, n) => ((Window)b).OnPageChanged(o as Page, n as Page));

public static readonly BindableProperty FlowDirectionProperty =
BindableProperty.Create(nameof(FlowDirection), typeof(FlowDirection), typeof(Window), FlowDirection.MatchParent, propertyChanging: FlowDirectionChanging, propertyChanged: FlowDirectionChanged);
Expand Down Expand Up @@ -586,31 +586,26 @@ toolbarElement.Toolbar is Toolbar tb &&
}
}

static void OnPageChanged(BindableObject bindable, object oldValue, object newValue)
void OnPageChanged(Page? oldPage, Page? newPage)
{
if (bindable is not Window window)
return;

var oldPage = oldValue as Page;
if (oldPage != null)
{
window.InternalChildren.Remove(oldPage);
InternalChildren.Remove(oldPage);
oldPage.HandlerChanged -= OnPageHandlerChanged;
oldPage.HandlerChanging -= OnPageHandlerChanging;
}

if (oldPage is Shell shell)
shell.PropertyChanged += ShellPropertyChanged;
shell.PropertyChanged -= ShellPropertyChanged;

var newPage = newValue as Page;
if (newPage != null)
{
window.InternalChildren.Add(newPage);
newPage.NavigationProxy.Inner = window.NavigationProxy;
window._menuBarTracker.Target = newPage;
InternalChildren.Add(newPage);
newPage.NavigationProxy.Inner = NavigationProxy;
_menuBarTracker.Target = newPage;
}

window.ModalNavigationManager.SettingNewPage();
ModalNavigationManager.SettingNewPage();

if (newPage != null)
{
Expand All @@ -624,24 +619,24 @@ static void OnPageChanged(BindableObject bindable, object oldValue, object newVa
if (newPage is Shell newShell)
newShell.PropertyChanged += ShellPropertyChanged;

window?.Handler?.UpdateValue(nameof(IWindow.FlowDirection));
Handler?.UpdateValue(nameof(IWindow.FlowDirection));
}

void OnPageHandlerChanged(object? sender, EventArgs e)
{
window.ModalNavigationManager.PageAttachedHandler();
window.AlertManager.Subscribe();
}
void OnPageHandlerChanged(object? sender, EventArgs e)
{
ModalNavigationManager.PageAttachedHandler();
AlertManager.Subscribe();
}

void OnPageHandlerChanging(object? sender, HandlerChangingEventArgs e)
{
window.AlertManager.Unsubscribe();
}
void OnPageHandlerChanging(object? sender, HandlerChangingEventArgs e)
{
AlertManager.Unsubscribe();
}

void ShellPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Shell.Title))
window?.Handler?.UpdateValue(nameof(ITitledElement.Title));
}
void ShellPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(Shell.Title))
Handler?.UpdateValue(nameof(ITitledElement.Title));
}

bool IWindow.BackButtonClicked()
Expand Down
4 changes: 2 additions & 2 deletions src/Controls/tests/Core.UnitTests/TestClasses/TestApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Microsoft.Maui.Controls.Core.UnitTests
{
public class TestApp : Application
{
ContentPage _withPage;
Page _withPage;
TestWindow _window;

public TestApp() : base(false)
Expand All @@ -29,7 +29,7 @@ protected override Window CreateWindow(IActivationState activationState)
return _window ?? new TestWindow(_withPage ?? new ContentPage());
}

public TestWindow CreateWindow(ContentPage withPage)
public TestWindow CreateWindow(Page withPage)
{
_withPage = withPage;
return (TestWindow)(this as IApplication).CreateWindow(null);
Expand Down
48 changes: 48 additions & 0 deletions src/Controls/tests/Core.UnitTests/WindowsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,54 @@ public void DefaultBoundsArePassedToCoreCorrectly()
Assert.Equal(double.NaN, coreWindow.MaximumHeight);
}

[Fact]
public void ShellTitleChangePropagatesToWindow()
{
var app = new TestApp();
var shell = new ShellTestBase.TestShell() { Title = "test" };
var window = app.CreateWindow();
bool fired = false;
window.Page = shell;
window.Handler = new WindowHandlerStub(new PropertyMapper<IWindow, WindowHandlerStub>()
{
[nameof(IWindow.Title)] = (_, _) => fired = true
});

// reset after setting handler
fired = false;
shell.Title = "new title";


Assert.Equal(shell.Title, (window as IWindow).Title);
Assert.True(fired);
}

[Fact]
public void PreviousShellDisconnectsFromWindowPropertyChanged()
{
var app = new TestApp();
var oldShell = new Shell() { Title = "Old Shell" };
var window = app.CreateWindow(oldShell);
bool fired = false;

window.Handler = new WindowHandlerStub(new PropertyMapper<IWindow, WindowHandlerStub>()
{
[nameof(IWindow.Title)] = (_, _) =>
{
fired = true;
}
});

window.Page = new Shell() { Title = "test" };

// reset after setting handler
fired = false;

oldShell.Title = "new title";
Assert.Equal("test", (window as IWindow).Title);
Assert.False(fired);
}

[Theory]
[InlineData(double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN)]
[InlineData(-1, -1, -1, -1, -1, -1, double.NaN, double.NaN)]
Expand Down