/// <summary> /// Creates a component of type <paramref name="componentType"/> and adds it as a child of <paramref name="parent"/>. If parameters are provided they will be set on the component. /// </summary> /// <param name="componentType"></param> /// <param name="parent"></param> /// <param name="parameters"></param> /// <returns></returns> public async Task <IComponent> AddComponent(Type componentType, IElementHandler parent, Dictionary <string, object> parameters = null) { try { return(await Dispatcher.InvokeAsync(async() => { var component = InstantiateComponent(componentType); var componentId = AssignRootComponentId(component); var rootAdapter = new NativeComponentAdapter(this, closestPhysicalParent: parent, knownTargetElement: parent) { Name = $"RootAdapter attached to {parent.GetType().FullName}", }; _componentIdToAdapter[componentId] = rootAdapter; SetParameterArguments(component, parameters); await RenderRootComponentAsync(componentId).ConfigureAwait(false); return component; }).ConfigureAwait(false)); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { HandleException(ex); return(null); } }
private static TElementType ConvertToType(IElementHandler elementHandler, string parameterName) { if (!(elementHandler is TElementType)) { throw new ArgumentException($"Expected parameter value of type '{elementHandler.GetType().FullName}' to be convertible to type '{typeof(TElementType).FullName}'.", parameterName); } return((TElementType)elementHandler); }
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); } } })); }
/// <summary> /// Creates a component of type <paramref name="componentType"/> and adds it as a child of <paramref name="parent"/>. /// </summary> /// <param name="componentType"></param> /// <param name="parent"></param> /// <returns></returns> public async Task AddComponent(Type componentType, IElementHandler parent) { await Dispatcher.InvokeAsync(async() => { var component = InstantiateComponent(componentType); var componentId = AssignRootComponentId(component); var rootAdapter = new NativeComponentAdapter(this, closestPhysicalParent: parent, knownTargetElement: parent) { Name = $"RootAdapter attached to {parent.GetType().FullName}", }; _componentIdToAdapter[componentId] = rootAdapter; await RenderRootComponentAsync(componentId).ConfigureAwait(false); }).ConfigureAwait(false); }
/// <summary> /// Creates a component of type <paramref name="componentType"/> and adds it as a child of <paramref name="parent"/>. If parameters are provided they will be set on the component. /// </summary> /// <param name="componentType"></param> /// <param name="parent"></param> /// <param name="parameters"></param> /// <returns></returns> public async Task <IComponent> AddComponent(Type componentType, IElementHandler parent, Dictionary <string, string> parameters = null) { return(await Dispatcher.InvokeAsync(async() => { var component = InstantiateComponent(componentType); var componentId = AssignRootComponentId(component); var rootAdapter = new NativeComponentAdapter(this, closestPhysicalParent: parent, knownTargetElement: parent) { Name = $"RootAdapter attached to {parent.GetType().FullName}", }; _componentIdToAdapter[componentId] = rootAdapter; SetNavigationParameters(component, parameters); await RenderRootComponentAsync(componentId).ConfigureAwait(false); return component; }).ConfigureAwait(false)); }
/// <summary> /// Creates a component of type <paramref name="componentType"/> and adds it as a child /// of <paramref name="parent"/>. /// </summary> /// <param name="componentType">The type of component to create.</param> /// <param name="parent">The parent to add the component to.</param> /// <param name="initialParameters">The <see cref="ParameterView"/> with the initial parameters.</param> /// <returns>A tuple of (<see cref="int"/> ComponentId, <see cref="IComponent"/> Component).</returns> protected async Task <(int ComponentId, IComponent Component)> AddComponent(Type componentType, IElementHandler parent, ParameterView initialParameters) { var result = await Dispatcher.InvokeAsync(() => { var component = InstantiateComponent(componentType); var componentId = AssignRootComponentId(component); var rootAdapter = new NativeComponentAdapter(this, closestPhysicalParent: parent, knownTargetElement: parent) { Name = $"RootAdapter attached to {parent.GetType().FullName}", }; _componentIdToAdapter[componentId] = rootAdapter; return(componentId, component); }).ConfigureAwait(false); await RenderRootComponentAsync(result.componentId, initialParameters).ConfigureAwait(false); return(result); }
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); } }));
public override string ToString() { return($"{nameof(NativeComponentAdapter)}: Name={Name ?? "<?>"}, Target={_targetElement?.GetType().Name ?? "<None>"}, #Children={Children.Count}"); }