Task RunWindowTest(IWindow window, Func <NavigationRootManager, Task> action) { return(InvokeOnMainThreadAsync(async() => { FrameworkElement frameworkElement = null; var content = (Panel)DefaultWindow.Content; try { var scopedContext = new MauiContext(MauiContext.Services); scopedContext.AddWeakSpecific(DefaultWindow); var mauiContext = scopedContext.MakeScoped(true); var windowManager = mauiContext.GetNavigationRootManager(); windowManager.Connect(window.Content); frameworkElement = windowManager.RootView; TaskCompletionSource <object> taskCompletionSource = new TaskCompletionSource <object>(); frameworkElement.Loaded += (_, __) => taskCompletionSource.SetResult(true); content.Children.Add(frameworkElement); await taskCompletionSource.Task; await action(windowManager); } finally { if (frameworkElement != null) { content.Children.Remove(frameworkElement); } } return Task.CompletedTask; })); }
Task CreateNavigationViewHandlerAsync(IStackNavigationView navigationView, Func <NavigationViewHandler, Task> action) { return(InvokeOnMainThreadAsync(async() => { FrameworkElement frameworkElement = null; var content = (Panel)DefaultWindow.Content; try { var mauiContext = MauiContext.MakeScoped(true); var handler = CreateHandler(navigationView, mauiContext); frameworkElement = handler.PlatformView; content.Children.Add(frameworkElement); if (navigationView is NavigationViewStub nvs && nvs.NavigationStack?.Count > 0) { navigationView.RequestNavigation(new NavigationRequest(nvs.NavigationStack, false)); await nvs.OnNavigationFinished; } await action(handler); } finally { if (frameworkElement != null) { content.Children.Remove(frameworkElement); } } })); }
Task RunWindowTest <THandler>(IWindow window, Func <THandler, Task> action) where THandler : class, IElementHandler { return(InvokeOnMainThreadAsync(async() => { var testingRootPanel = (WPanel)MauiProgram.CurrentWindow.Content; IElementHandler newWindowHandler = null; NavigationRootManager navigationRootManager = null; try { var scopedContext = new MauiContext(MauiContext.Services); scopedContext.AddWeakSpecific(MauiProgram.CurrentWindow); var mauiContext = scopedContext.MakeScoped(true); navigationRootManager = mauiContext.GetNavigationRootManager(); navigationRootManager.UseCustomAppTitleBar = false; newWindowHandler = window.ToHandler(mauiContext); var content = window.Content.Handler.ToPlatform(); await content.OnLoadedAsync(); await Task.Delay(10); if (typeof(THandler).IsAssignableFrom(newWindowHandler.GetType())) { await action((THandler)newWindowHandler); } else if (typeof(THandler).IsAssignableFrom(window.Content.Handler.GetType())) { await action((THandler)window.Content.Handler); } } finally { if (navigationRootManager != null) { navigationRootManager.Disconnect(); } if (newWindowHandler != null) { newWindowHandler.DisconnectHandler(); } // Set the root window panel back to the testing panel if (testingRootPanel != null && MauiProgram.CurrentWindow.Content != testingRootPanel) { MauiProgram.CurrentWindow.Content = testingRootPanel; await testingRootPanel.OnLoadedAsync(); await Task.Delay(10); } } })); }
Task RunWindowTest <THandler>(IWindow window, Func <THandler, Task> action) where THandler : class, IElementHandler { return(InvokeOnMainThreadAsync(async() => { var testingRootPanel = (WPanel)MauiProgram.CurrentWindow.Content; IElementHandler newWindowHandler = null; NavigationRootManager navigationRootManager = null; try { var scopedContext = new MauiContext(MauiContext.Services); scopedContext.AddWeakSpecific(MauiProgram.CurrentWindow); var mauiContext = scopedContext.MakeScoped(true); navigationRootManager = mauiContext.GetNavigationRootManager(); MauiContext .Services .GetRequiredService <WWindow>() .SetWindowHandler(window, mauiContext); newWindowHandler = window.Handler; var content = window.Content.Handler.ToPlatform(); await content.OnLoadedAsync(); await Task.Delay(10); if (typeof(THandler).IsAssignableFrom(newWindowHandler.GetType())) { await action((THandler)newWindowHandler); } else if (typeof(THandler).IsAssignableFrom(window.Content.Handler.GetType())) { await action((THandler)window.Content.Handler); } else if (window.Content is ContentPage cp && typeof(THandler).IsAssignableFrom(cp.Content.Handler.GetType())) { await action((THandler)cp.Content.Handler); } else { throw new Exception($"I can't work with {typeof(THandler)}"); } } finally { if (navigationRootManager != null) { navigationRootManager.Disconnect(); } if (newWindowHandler != null) { newWindowHandler.DisconnectHandler(); } // Set the root window panel back to the testing panel if (testingRootPanel != null && MauiProgram.CurrentWindow.Content != testingRootPanel) { MauiProgram.CurrentWindow.Content = testingRootPanel; await testingRootPanel.OnLoadedAsync(); await Task.Delay(10); } // reset the appbar title to our test runner MauiProgram .CurrentWindow .GetWindow() .Handler .MauiContext .GetNavigationRootManager() .UpdateAppTitleBar(true); } }));
void SetCurrent(Page newPage, Page previousPage, bool popping, Action?completedCallback = null) { try { if (popping) { RemovePage(previousPage); } else if (newPage.BackgroundColor.IsDefault() && newPage.Background.IsEmpty) { RemovePage(previousPage); } if (popping) { previousPage.Handler = null; // Un-parent the page; otherwise the Resources Changed Listeners won't be unhooked and the // page will leak previousPage.Parent = null; } if (Container == null || newPage == null) { return; } if (!popping) { var modalContext = MauiContext .MakeScoped(registerNewNavigationRoot: true); newPage.Toolbar ??= new Toolbar(newPage); _ = newPage.Toolbar.ToNative(modalContext); var windowManager = modalContext.GetNavigationRootManager(); windowManager.Connect(newPage); Container.Children.Add(windowManager.RootView); } else { var windowManager = newPage.FindMauiContext()?.GetNavigationRootManager() ?? throw new InvalidOperationException("Previous Page Has Lost its MauiContext"); if (!Container.Children.Contains(windowManager.RootView)) { Container.Children.Add(windowManager.RootView); } } completedCallback?.Invoke(); } catch (Exception error) { //This exception prevents the Main Page from being changed in a child //window or a different thread, except on the Main thread. //HEX 0x8001010E if (error.HResult == -2147417842) { throw new InvalidOperationException("Changing the current page is only allowed if it's being called from the same UI thread." + "Please ensure that the new page is in the same UI thread as the current page."); } throw; } }